反射内省JaveBean与简单工厂设计模式(二)

2014-11-24 09:39:54 · 作者: · 浏览: 1
flectDemo {

private int pos ;
public String name;

private int size ;
private final static double PI = 3.1415926;

private ArrayList alist = new ArrayList();

/**
* 静态方法,反射调用invork时,第一个参数为null即无作用对象,由于也没有参数。
* 所以最终的反射在调用时,肯定是invork(null)即可。
* @return
*/
public static double getPI(){
return PI;
}

/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
getClassTest();
applyReflectChangeObjValDemo();
reflectInvorkArrayDeom();
//获取一个类的方法签名、构造函数签名、成员变量等。
printClass("java.lang.String");
arraysAsListTest();

}

public static void getClassTest() throws Exception{

/*
三种方式来获得Class对象,三种方式得出来的对象都是一个都是此类的字节码对象
1> 对象.getClass()
2> 类名.class 不会加载类,即不会静态初始化等
3> Class.forName(完全限定类名) 会加载类,会静态初始化
*/

String str1 = "abc";
Class c1 = str1.getClass();
Class c2 = String.class;
Class c3 = Class.forName("java.lang.String");

System.out.println("c1==c2::"+(c1==c2)); // true
System.out.println("c2==c3::"+(c2==c3)); // true

//Class对象中用isPrimitive()方法可判断是否基本类型字节码
System.out.println("c1.isPrimitive()=="+c1.isPrimitive()); //false

Class c4 = int.class;
System.out.println("c1.isPrimitive()=="+c4.isPrimitive()); // true
System.out.println("c3==c4::"+(c3==c4)); // false
//包装类,可使用类名.TYPE得到基本类型的Class对象
Class c5 = Integer.TYPE;
System.out.println("c4==c5::"+(c4==c5)); // true


//反射得到实例对象的,有两个方法一种是先得到反射中的构造器,通过构造器的newInstance来搞定
//另一种是直接通过class的newInstance,但这个方法是要求类必须有个无参的构造方法
Class strCl = Class.forName("java.lang.String");
Constructor strCon = strCl.getConstructor(StringBuilder.class);
String str = (String)strCon.newInstance(new StringBuilder("sdf"));
String strr = (String)strCl.newInstance();

}

private static void arraysAsListTest() {
int[] a1 = new int[]{4,5,6};
List l1 = Arrays.asList(a1); //因为a1不是object[]数组,不会用jdk1.4中的asList(Object[] objs)来调用
//而是用jdk1.5中的asList(T... args)所以int[]当成了一个Object来传入,此
//此List中只有一个元素,是int[]型的 Object。
System.out.println(l1+"-----------"+l1.size()); //size为1,只有一个元素 打印的是:[[I@10b30a7]-----------1
for(int i=0;i
System.out.print(l1.get(i)+" ,"); //[I@c17164 只有此元素
}
}

/*
* 总结:反射在调用带数组参数的方法时,一定要注意invork方法调用的情况,因为传入invork方法是一个数组的话,编译器会采用JDK1.4折方法特性将数组拆包,
* 数组中每个元素将作为一个参数传入到相应方法中。这样肯定会与之前的getMethod中的数组.class有冲突,会报
* java.lang.IllegalArgumentException: wrong number of arguments 参数数量不对了。
* 为了解决此问题,有两种方法,一种是不让JDK1.4插手,那么就可将数组前面强转成Object,这样编译器会使用JDK1.5的,不会将数组拆包。
* 如:m1.invoke(rd, (Object)new String[]{"abc","bcd"});
* 另一种方法是,还是让JDK1.4编,那么外面再用一个数组包起,这个数组。这样JDK1.4遇到这个数组的数组,拆包后还是一样数组正好与getMethod中是一致的。
* 如m1.invoke(rd, new Object[]{new String[]{"abc","bcd"}});
*
* */
private static void