23接合收数组参数的成员方法进行反射24 数组与Object的关系及其反射类型25 数组的反射应用
23对接收数组参数的成员方法进行反射
package cn.zyj23.review; import java.lang.reflect.Method; public class ReflectTest { public static void main(String[] args) throws Exception { //TestArguments.main(new String[]{"111","222","333"}); String startingClassName = args[0]; Method mainMethod = Class.forName(startingClassName).getMethod("main", String[].class); //mainMethod.invoke(null, new Object[]{new String[]{"111","222","333"}}); mainMethod.invoke(null, (Object)new String[]{"111","222","333"});//效果同上 } } class TestArguments{ public static void main(String[] args){ for(String arg : args){ System.out.println(arg); } } }
启动java程序的main方法的参数是一个字符串数组,即public static void main(String[] args),通过反射方式来调用这个main方法时,如何为invoke方法传递参数呢?按jdk1.5的语法,整个数组时一个参数,而jdk1.4的语法,数组中额度每个元素对应一个参数,当把一个字符串数组作为参数传递给invoke方法时,javac会到底按照哪种语法进行处理呢?jdk1.5肯定要兼容jdk1.4的语法,会按照jdk1.4的语法进行处理,即把数组打撒成为若干个单独的参数。所以在给main方法传递参数时,不能使用代码mainMethod.invoke(null, new String[]{"11","22","33"});javac只把他当做jdk1.4的语法进行理解,而不是jdk1.5,因此会出现参数类型不对的问题。
解决方法:
mainMethod.invoke(null, new Object[]{new String[]{"11","22","33"}});
mainMethod.invoke(null,(Object)new String[]{"11","22","33"});//编译器会做特殊处理,编译时不会吧参数当做数组看待,也就不会数组打撒成若干参数了
24 数组与Object的关系及其反射类型。
int[] a1=new int[]{1,2,3};
int[] a2=new int[]{4};
int[][] a3=new int[2][3];
String [] a4=new String[]{"a","b","c"};
System.out.println(a1.getClass().getName());//[I
System.out.println(a2.getClass().getName());//[I
System.out.println(a3.getClass().getName());//[[I
System.out.println(a4.getClass().getName());//[Ljava.lang.String;
1、具有相同维数和元素类型的数组属于同一个类型,即具有相同的Class实例对象
System.out.println(a1.getClass() == a2.getClass());
//System.out.println(a1.getClass() == a4.getClass());//报错,看错误提示
//System.out.println(a1.getClass() == a3.getClass());//报错,看错误提示
2、代表数组的Class实例对象的getSuperClass()方法返回的父类为Object类对应的Class。
// getSuperclass
// public Class<? super T> getSuperclass()返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的超类的 Class。如果此 Class 表示 Object 类、一个接口、一个基本类型或 void,则返回 null。如果此对象表示一个数组类,则返回表示该 Object 类的 Class 对象。
// 返回:
// 此对象所表示的类的超类。
System.out.println(a1.getClass().getSuperclass().getName());//java.lang.Object
System.out.println(a2.getClass().getSuperclass().getName());//java.lang.Object
System.out.println(a3.getClass().getSuperclass().getName());//java.lang.Object
System.out.println(a4.getClass().getSuperclass().getName());//java.lang.Object
Object obj1=a1;
Object obj2=a3;
Object obj3=a3;
Object obj4=a4;
3、基本类型的一位数组可以被当作Object类型使用,不能当做Object[]类型使用;非基本类型的一维数组,既可以当做Object类型使用也可以当做Object[]类型使用
//Object[] objs1=a1;//int的不是Object
//Object[] objs2=a2;
Object[] objs3=a3;//int[]是个Object对象
Object[] objs4=a4;//字符串数组里的字符串是Object,即Object数组里的Object
Object[] 与String[]没有父子关系,Object与String有父子关系,所以new Object[]{“aaa”,”bb”}不能强制转换成new String[]{“aaa”,”bb”};,Object x = “abc”能强制转换成String x = “abc”。
main.invoke(null, (Object)(new Object[]{“aaa”,“xxx”}));不能调用public static void main(String [] args)
4、Arrays.asList()(Arrays.deepToString())方法处理int[]和String[]时的差异。
jdk1.4 public static <T> List<T> asList(Object[] a)
jdk1.5 public static <T> List<T> asList(T... a)
为了考虑兼容性先给jdk1.4的运行,当jdk1.4不能处理时交由jdk1.5处理,例如System.out.println(Arrays.asList(a4));,a4为String [],jdk1.4可以处理,所以得到了每个的值,如果是a1时,即int[],他不是Object[] a,所以jdk1.4不能处理,就交给了jdk1.5处理了,而jdk1.5把int[]当做了Object对象处理了,得到了[[I@10b30a7]
System.out.println(Arrays.toString(a1));//[1, 2, 3]//public static String toString(int[] a)
System.out.println(Arrays.toString(a2));//[4]//public static String toString(int[] a)
System.out.println(Arrays.toString(a3));//[[I@14318bb, [I@ca0b6]//public static String toString(Object[] a)
System.out.println(Arrays.toString(a4));//[a, b, c]//public static String toString(Object[] a)
System.out.println(Arrays.asList(a1));//[[I@10b30a7]//jdk1.5 public static <T> List<T> asList(T... a)
System.out.println(Arrays.asList(a2));//[[I@1a758cb]//jdk1.5 public static <T> List<T> asList(T... a)
System.out.println(Arrays.asList(a3));//[[I@14318bb, [I@ca0b6]//jdk1.4 public static <T> List<T> asList(Object[] a)
System.out.println(Arrays.asList(a4));//[a, b, c]//jdk1.4 public static <T> List<T> asList(Object[] a)
25 数组的反射应用
1,Array工具类用于完成对数组的反射操作。
private static void printObject(Object obj){
Class cla=obj.getClass();
if (cla.isArray()) {
int len=Array.getLength(obj);
for (int i = 0; i < len; i++) {
System.out.println(Array.get(obj, i));
}
} else {
System.out.println(obj);
}
}