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

2014-11-24 09:39:54 · 作者: · 浏览: 5
reflectInvorkArrayDeom() {
ReflectDemo rd = new ReflectDemo();

Method m1 = null ;
try{
Class lc = rd.getClass();
int[] intArr = new int[]{3,5};
m1 = lc.getMethod("printIntArray", int[].class);
m1.invoke(rd, intArr);

String[] strArr = new String[]{"abc","bcd"};
m1 = lc.getMethod("printStringArray", String[].class);
//m1.invoke(rd, strArr); //这样调用是有问题的,因为在invork方法发现第二个参数是String[]数组
//此时invork会用1.4的Object[],在1.4中第二个参数会先被拆包,拆成多个参数传与相应的方法中
//但此时已经与getMethod中声明的String[].class有冲突了,所以会报IllegalArgumentException异常
//java.lang.IllegalArgumentException: wrong number of arguments 参数数量不对
//解决这个问题有两个方法,一是用jdk1.5提供的可变参数,那么为让编译器知道去调用1.5的,那么就要将数组变成一个对象。
m1.invoke(rd, (Object)strArr);
//另一个解决方法是,1.4的是不要个数组吗,给个数组它new Object[],这个数组里呢,再传入个String[]数组,这样编译器在使用1.4的时
//先将数组拆包后,取去其中元素,正好是一个数组与上面的String[].class是吻合的。即可以调用了。
m1.invoke(rd, new Object[]{strArr});


Integer[] integerArr = new Integer[]{12,56};
m1 = lc.getMethod("printIntegerArray", Integer[].class);
//m1.invoke(rd, integerArr); 同时这样调用也是有问题的
m1.invoke(rd, (Object)integerArr);
}catch(Exception e){
e.printStackTrace();
}

}

/**
* printClass用于打印,运行时才知道来的类,具体哪些构造方法,哪些方法以及哪些变量
* @param className
*/
private static void printClass(String className) {
ArrayList al = new ArrayList();
Class clazz = null ;
try {
clazz = Class.forName(className);
} catch (ClassNotFoundException e) {
throw new RuntimeException("类名有问题,请重新输入");

}
String modifierName = Modifier.toString(clazz.getModifiers());
StringBuilder sb = new StringBuilder();
if(modifierName != null && modifierName.length()>0){
sb.append(modifierName);
}

sb.append(" "+clazz.getName()+"{");
sb.append(System.getProperty("line.separator"));
printConstructors(clazz,sb);
printMethods(clazz,sb);
printFields(clazz,sb);

sb.append(System.getProperty("line.separator"));
sb.append("}");
System.out.println(sb.toString());
}

/**
* 打印运行时类的,变量。
* @param clazz 运行时类的字节码
* @param sb 打印的内容先用StringBuilder缓存下
*/
private static void printFields(Class clazz, StringBuilder sb) {
sb.append(System.getProperty("line.separator"));
sb.append("\t");
Field[] fields = clazz.getFields();
for(Field field:fields){
sb.append(Modifier.toString(field.getModifiers()));
sb.append(field.getName());
sb.append(System.getProperty("line.separator"));
sb.append("\t");
}
}

/**
* 打印运行时类的方法。
* @param clazz 运行时类的字节码
* @param sb 打印的内容先用StringBuilder缓存下
*/
private static void printMethods(Class clazz, StringBuilder sb) {
sb.append(System.getProper