----------------------ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------
1.享元模式
在自动拆箱和装箱中(JDK1.5引入),针对Integer类型对象所存储的值的大小,对象表现出不同状态。public class Demo {
public static void main(String[] args) {
Integer i1 = 3; //自动装箱 相当于Integer i1 = new Integer(3);
Integer i2 = 3;
System.out.println(i1 == i2);
Integer i3 = 183;
Integer i4 = 183;
System.out.println(i3 == i4);
Integer i5 = Integer.valueOf(6); //将6打包成一个Integer对象
Integer i6 = Integer.valueOf(6);
System.out.println(i5 == i6);
Integer i7 = Integer.valueOf(186);
Integer i8 = Integer.valueOf(186);
System.out.println(i7 == i8);
}
}
注:结果为true false true false,一个系统中如果有多个相同的对象,那么只共享一份就可以了,不必每个都去实例化一个对象。对于Integer对象,当值在-128~127之间时,只会装箱成同一个对象,当值超过此范围就会在内存中创建新的对象。2.单例设计模式中懒汉式线程安全问题
a.单例public class ThreadDemo {
public static void main(String[] args) {
SingleDemo s1 = SingleDemo.getInstance();
SingleDemo s2 = SingleDemo.getInstance();
System.out.println(s2 == s2);
}
}
class SingleDemo {
private static SingleDemo s = null;
private SingleDemo(){}
public static SingleDemo getInstance(){
if(s == null){
s = new SingleDemo();
}
return s;
}
}
注:运行结果一直都是true,说明单线程下是没问题的,下面写个多线程来访问单例 public class ThreadDemo implements Runnable {
Set singles = new HashSet();
public void run() {
Single s = Single.getInstance();
singles.add(s);
}
public static void main(String[] args) {
ThreadDemo t = new ThreadDemo();
for(int i=0; i<10; i++){
new Thread(t).start();
System.out.println(t.singles);
}
}
}
class Single {
private static Single s = null;
private Single(){}
public static Single getInstance(){
if(s == null){
s = new Single();
}
return s;
}
}
运行结果如下:
class Single {
private static Single s = null;
private Single(){}
public static synchronized Single getInstance(){
if(s == null){
s = new Single();
}
return s;
}
}
加入同步函数后线程安全问题解决了,运行多次都是获取同一个实例,不会出现2个实例的情况了
class Single {
private static Single s = null;
private Single(){}
public static Single getInstance(){
/*如果第一个线程获取到了单例的实例对象,后面的线程再获取实例的时候不需要进入同步代码块中了*/
if(s == null){
//同步代码块用的锁是单例的字节码文件对象,且只能用这个锁
synchronized(Single.class){
if(s == null){
s = new Single();
}
}
}
return s;
}
}
注:用这种方式解决了懒汉式的线程安全问题,也提高了效率,但是在实际开发中还是用饿汉式的比较多,毕竟这个代码比较多,比较繁琐。3.枚举
枚举中的每个元素都是枚举对象,枚举有默认的构造方法,当第一次使用枚举时,就会调用构造方法对每个枚举对象进行初始化。public class EnumerationDemo {
public static void main(String[] args) {
Weekday weekday = Weekday.SUN;
System.out.println(weekday.name());
System.out.println(weekday.ordinal());
System.out.println(weekday.getClass());
System.out.println(weekday.hashCode());
System.out.println(weekday.valueOf("MON"));
System.out.println(weekday.values().length);
}
}
enum Weekday{
SUN,MON,TUE,WED,THI,FRI,SAT;
private Weekday(){
System.out.println("first");
}
private Weekday(int i){
System.out.println("second");
}
}
交通灯枚举创建:
public enum TrafficLamp{
RED(30){
public TrafficLamp nextLamp(){ //new实例时,使用匿名内部类,实现子类的抽象方法
return YELLOW;
}
},
GREEN(45){
public TrafficLamp nextLamp(){
return YELLOW;
}
},
YELLOW(5){
public TrafficLamp nextLamp(){
return GREEN;
}
};
public abstract TrafficLamp nextLamp(); //抽象方法
private int time;
private TrafficLamp(int time){ //带参构造方法
this.time = time;
}
}
4.反射
反射就是把java类中的各种成分映射成相应的java类。public class ReflectDemo {
public static void main(String[] args) throws Exception {
String str = "han";
Class cls1 = String.class;
Class cls2 = str.getClass();
Class cls3 = Class.forName("java.lang.String");
System.out.println(cls1 == cls2);//true
System.out.println(cls1 == cls3);//true
}
}
注:八中基本类型(byte,short,char,int,long,float,double,boolean)和void都有自己的字节码。每种类型的字节码在jvm中只存在一份。public class ReflectPointDemo {
private int x;
public int y;
public ReflectPointDemo(int x, int y) {
super();
this.x = x;
this.y = y;
}
}
2)在测试类中测试private static void replaceStringValue(ReflectPointDemo rpd) throws Exception {
Field[] fields = rpd.getClass().getFields();
for(Field field : fields){
if(field.getType() == String.class){
String oldVal = (String)field.get(rpd);
String newVal = oldVal.replace('b', 'a');
field.set(rpd, newVal);
}
}
}
d.成员方法的反射class ArgumentTest{
public static void main(String[] args) {
for(String str : args){
System.out.println(str);
}
}
}
2)在主方法中添加以下语句,运行程序传入参数private static void printObject(Object obj) {
Class c = obj.getClass();
if(c.isArray()){
for(int i=0; i
2)在主方法中定义变量并调用方法public class PropertiesDemo {
public static void main(String[] args) throws Exception {
InputStream in = new FileInputStream("config.properties");//new字节流对象
Properties p = new Properties();
p.load(in);//加载数据
in.close();
String className = p.getProperty("className");//取出文件中的字符串值
Collection c = (Collection)Class.forName(className).newInstance();//利用反射取得字符串所对应类对象
//Collection c = new HashSet();
ReflectPointDemo rpd1 = new ReflectPointDemo(3, 3);
ReflectPointDemo rpd2 = new ReflectPointDemo(5, 5);
ReflectPointDemo rpd3 = new ReflectPointDemo(6, 6);
c.add(rpd1);
c.add(rpd2);
c.add(rpd3);
c.add(rpd1);
System.out.println(c.size());
}
}
5.javabeanpublic class IntroSpectorDemo {
public static void main(String[] args) throws Exception {
PersonDemo p = new PersonDemo(5,6);
String propertyName = "x";
PropertyDescriptor pd = new PropertyDescriptor(propertyName, PersonDemo.class);
Method methodGetX = pd.getReadMethod();
Object obj = methodGetX.invoke(p);
System.out.println(obj);
Method methodSetX = pd.getWriteMethod();
methodSetX.invoke(p,12);
System.out.println(p.getX());
}
}
public class GenericDemo {
public static void main(String[] args) {
Map maps = new HashMap();//指定Map中存放的元素类型
maps.put("a", 1);
maps.put("b", 2);
maps.put("c", 3);
Set> sets = maps.entrySet();//通过Map的entrySet()方法取得集合中的键值对
for(Map.Entry entry : sets){
System.out.println(entry.getKey() + "," + entry.getValue());//循环遍历输出集合中元素
}
}
}
public class MyClassLoader extends ClassLoader{
public static void main(String[] args){
String srcPath = args[0];
String destDir = args[1];
FileInputStream fis = new FileInputStream(srcPath);
String destFileName = srcPath.substring(srcPath.lastIndexOf('\\')+1);
String destPath = destSrc + "\\" + destFileName;
FileOutputStream fos = new FileOutputStream(destPath);
cypher(fis,fos);
fis.close();
fos.close();
}
//加密,解密程序
private static void cypher(InputStream is,OutputStream os)throws Exeption{
int b = -1;
while((b=is.read())!=-1){
os.write(b ^ 0xff);
}
}
private String classDir;
protected Class> findClass(String name) throws ClassNotFoudException{
String classFileName = classDir + "\\"+name+".class";
try{
FileInputStream fis = new FileInputStream(classFileName);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
cypher(fis,bos);
fis.close();
byte[] bytes = bos.toByteArray();
return defineClass(bytes,0,bytes.length);
}catch(Exception x){}
return super.findClass(name);
}
public MyClassLoader(){}
public MyClassLoader(String classDir){
this.classDir = classDir;
}
}
public class ClassDemo {
public String toString() {
return "hanxuhui";
}
}
2)自定义类加载器加载ClassDemo类的ClassDemo.class文件
public class ClassLoaderDemo extends ClassLoader{
public static void main(String[] args)throws Exception{
Class clazz = new ClassLoaderDemo().loadClass("ClassDemo.class");
System.out.println(clazz.getName());
Object obj = (Object)clazz.newInstance();
System.out.println(obj);
}
protected Class> findClass(String name)throws ClassNotFoundException{
try{
FileInputStream fis = new FileInputStream(name);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Change.lock(fis,baos);
fis.close();
byte[] bytes = baos.toByteArray();
return defineClass(null,bytes,0,bytes.length);
}catch(Exception e){
System.out.println(e);
}
return null;
}
}
class Change{
public static void main(String[] args)throws Exception{
FileInputStream fis = new FileInputStream(args[0]);
FileOutputStream fos = new FileOutputStream(args[1]);
lock(fis,fos);
}
public static void lock(InputStream is,OutputStream os)throws Exception{
int b = -1;
while((b=is.read())!=-1){
os.write(b ^ 0xff);
}
is.close();
os.close();
}
}
public class ProxyTest {
public static void main(String[] args) throws Exception {
Class clazzProxy1 = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);
//对于class,我们通常认为它是字节码
System.out.println(clazzProxy1.getName());
System.out.println("begin constructors list-----:");
Constructor[] constructors = clazzProxy1.getConstructors(); //得到它的构造方法
for (Constructor constructor : constructors) {
String name = constructor.getName();
StringBuilder sBuilder = new StringBuilder(); //用StringBuilder效率更高一点
sBuilder.append('(');
Class[] clazzParams = constructor.getParameterTypes(); //得到参数的类型,返回的是一个class的数组。
for (Class clazzParam : clazzParams) { //取出每个参数的名字
sBuilder.append(clazzParam.getName()).append(',');
}
if (clazzParams != null && clazzParams.length != 0)
sBuilder.deleteCharAt(sBuilder.length() - 1); //去掉最后一个参数
sBuilder.append(')');
System.out.println(sBuilder.toString());
}
//StringBuilder与StringBuffered的区别:
//在动态上,都是往字符串中添加字符,在单线程下,用StringBuilder效率要高一点,在多线程下StringBufferd要高点
System.out.println("----------begin methods list----------");
Method[] methods = clazzProxy1.getMethods();
for (Method method : methods) {
String name = method.getName();
StringBuilder sBuilder = new StringBuilder(name);
sBuilder.append('(');
Class[] clazzParams = method.getParameterTypes();
for (Class clazzParam : clazzParams) {
sBuilder.append(clazzParam.getName()).append(',');
}
if (clazzParams != null && clazzParams.length != 0)
sBuilder.deleteCharAt(sBuilder.length() - 1);
sBuilder.append(')');
System.out.println(sBuilder.toString());
}
// 创建动态类的实例对象用调用方法
System.out.println("-----begin create instance-----");
// Object obj=clazzProxy1.newInstance();//不能这能调用构造参数的实例化方法。
// 构造方法接受一个参数,然后再去调用构造方法。
Constructor constructor = clazzProxy1.getConstructor(InvocationHandler.class);
class MyInvocationHander1 implements InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return null;
}
}
Collection proxy1 = (Collection) constructor.newInstance(new MyInvocationHander1());
System.out.println(proxy1);
proxy1.clear();// 如果不报空指针异常,就说明这个对象是有的。
// proxy1.size();//出错了,那么就判定size方法出问题了,因为size方法有返回值,clear方法没有。
Collection proxy2 = (Collection) constructor
.newInstance(new InvocationHandler() {
public Object invoke(Object proxy, Method method,Object[] args) throws Throwable {
return null;
}
});
// 代理对象
Collection proxy3 = (Collection) Proxy.newProxyInstance(
Collection.class.getClassLoader(),
new Class[] { Collection.class }, new InvocationHandler() {
public Object invoke(Object proxy, Method method,Object[] args) throws Throwable {
ArrayList target = new ArrayList();
long beginTime = System.currentTimeMillis();
Object retVal = method.invoke(target, args);
long endTime = System.currentTimeMillis();
System.out.println(method.getName() + " running time of: " + (endTime - beginTime) + "ms");
return retVal;
}
});
proxy3.add("zxx");// 每调用一个add方法,invoke就被执行
proxy3.add("lhm");
proxy3.add("hjl");
System.out.println(proxy3.size());
}
}
d.创建动态代理类:public class MyAdvice implements Advice {
long beginTime = 0;
public void afterMethod(Method method) {
System.out.println("开始啦!");
long endTime = System.currentTimeMillis();
System.out.println(method.getName() + " running time of " + (endTime - beginTime));
}
public void beforeMethod(Method method) {
System.out.println("结束啦!");
beginTime = System.currentTimeMillis();
}
}
public class ProxyDemo {
public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Class clazz = Proxy.getProxyClass(Collection.class.getClassLoader(), new Class[]{Collection.class});
Constructor[] cons = clazz.getConstructors();
for(Constructor con : cons){
System.out.println(con.getName()+"..."+con.getParameterTypes()[0].getName());
}
Method[] methods = clazz.getMethods();
for(Method method : methods){
System.out.println(method.getName()+"..."+method.getParameterCount());
}
Constructor constructor = clazz.getConstructor(InvocationHandler.class);
class Invocat implements InvocationHandler{
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return null;
}
}
Collection instance = (Collection)constructor.newInstance(new Invocat());
System.out.println(instance.toString());
instance.clear();
instance.hashCode();
}
}
3)Proxy.newProxyInstance(ClassLoader,Class>,InvocationHandler)可以直接创建代理类对象。InvocationHandler接口中的invoke方法的作用 是对对象中方法进行操作,添加相应的操作。实现InvocationHandler接口,并计算各个方法的运行时间
new InvocationHandler{
ArrayList target = new ArrayList();
public Object invoke(Object proxy,Method method,Object[] args)throws Throwable{
long beginTime = System.currentTimeMillis();
Object retVal = method.invoke(target,args);
long endTime = System.currentTimeMillis();
System.out.println(endTime-beginTime);
return retVal;
}
}
public class BeanFactory {
Properties props = new Properties();
public BeanFactory(InputStream ips){
try {
props.load(ips);
} catch (IOException e) {
e.printStackTrace();
}
}
public Object getBean(String name){
String className = props.getProperty(name);
Object bean = null;
try {
Class clazz = Class.forName(className);
bean = clazz.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
if(bean instanceof ProxyFactoryBean){
Object proxy = null;
ProxyFactoryBean proxyFactoryBean = (ProxyFactoryBean)bean;
try {
Advice advice = (Advice)Class.forName(props.getProperty(name + ".advice")).newInstance();
Object target = Class.forName(props.getProperty(name + ".target")).newInstance();
proxyFactoryBean.setAdvice(advice);
proxyFactoryBean.setTarget(target);
proxy = proxyFactoryBean.getProxy();
} catch (Exception e) {
e.printStackTrace();
}
return proxy;
}
return bean;
}
}
public class ProxyFactoryBean {
private Advice advice;
private Object target;
public Advice getAdvice() {
return advice;
}
public void setAdvice(Advice advice) {
this.advice = advice;
}
public Object getTarget() {
return target;
}
public void setTarget(Object target) {
this.target = target;
}
public Object getProxy() {
Object proxy3 = Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),
new InvocationHandler() {
public Object invoke(Object proxy, Method method,Object[] args) throws Throwable {
advice.beforeMethod(method);
Object retVal = method.invoke(target, args);
advice.afterMethod(method);
return retVal;
}
});
return proxy3;
}
}
public class AopFrameworkTest {
public static void main(String[] args) throws Exception {
InputStream ips = AopFrameworkTest.class.getResourceAsStream("config.properties");
Object bean = new BeanFactory(ips).getBean("xxx");
System.out.println(bean.getClass().getName());
((Collection)bean).clear();
}
}
注:工厂类BeanFactory负责创建目标类或代理类的实例对象,并通过配置文件实现切换。其getBean方法根据参数字符串返回一个相应的实例对象,如果参数字符串在配置文件中对应的类名不是ProxyFactoryBean,则直接返回该类的实例对象,否则,返回该类实例对象的getProxy方法返回的对象。