今天在看张孝祥老师讲的一个泛型的知识点时,碰到了一个问题,张老师说泛型只是给编译器看的,以张老师举的例子说明:
都是ArrayList类型的对象,一个是String型(ArrayList<String>)arr1,另一个是Integer型(ArrayList<Integer>)arr2,这两个对象在编译完成后生成的字节码是相同的,利用反射调用add方法时应该可以把泛型屏蔽的,但是我碰到了下面的问题,代码如下: ArrayList<Integer> arr1 = new ArrayList<Integer>();
arr1.getClass().getMethod("add", Object.class).invoke(arr1, "abc");
System.out.println(arr1.get(0));上面这个没有问题,可以把泛型屏蔽掉,但是下面的却不行: ArrayList<String> arr2 = new ArrayList<String>();
arr2.getClass().getMethod("add", Object.class).invoke(arr2, 2);
System.out.println(arr2.get(0));运行报了异常:
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
at day1.GenericTest.main(GenericTest.java:30)
不知道为什么,String型的可以屏蔽,Integer的却不行,有哪位高手能指点一下。
都是ArrayList类型的对象,一个是String型(ArrayList<String>)arr1,另一个是Integer型(ArrayList<Integer>)arr2,这两个对象在编译完成后生成的字节码是相同的,利用反射调用add方法时应该可以把泛型屏蔽的,但是我碰到了下面的问题,代码如下: ArrayList<Integer> arr1 = new ArrayList<Integer>();
arr1.getClass().getMethod("add", Object.class).invoke(arr1, "abc");
System.out.println(arr1.get(0));上面这个没有问题,可以把泛型屏蔽掉,但是下面的却不行: ArrayList<String> arr2 = new ArrayList<String>();
arr2.getClass().getMethod("add", Object.class).invoke(arr2, 2);
System.out.println(arr2.get(0));运行报了异常:
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
at day1.GenericTest.main(GenericTest.java:30)
不知道为什么,String型的可以屏蔽,Integer的却不行,有哪位高手能指点一下。
arr2.getClass().getMethod("add", Object.class).invoke(arr2, 2);
还是这行?
System.out.println(arr2.get(0));如果是第二个,我猜是调用了System.out.println(String str)这个方法,而你传入的是Integer,你可以试试:System.out.println(arr2.get(0)+"");
这个也是可以屏蔽的,错误原因是由于你的System.out.println(arr2.get(0));
ArrayList<String> arr2 = new ArrayList<String>();
arr2.getClass().getMethod("add", Object.class).invoke(arr2, 2);
System.out.println(String.valueOf(arr2.get(0)));
这样程序就正常OK,输出为2!
System.out.println(arr2.get(0)+""); 这样 也是不行的
可以直接 System.out.println(arr2),其实 你已经绕开了,已经添加进去了
//还得用反射取出来才可以骗过编译器
public static void main(String[] args)throws Exception {
ArrayList<String> arr2 = new ArrayList<String>();
arr2.getClass().getMethod("add", Object.class).invoke(arr2, 2);
System.out.println(arr2.getClass().getMethod("get",int.class).invoke(arr2, 0));
//System.out.println(arr2.get(0));//这里编译器认为取出来的是String
}
public static void main(String args[]) throws Exception {
ArrayList<Integer> arr1 = new ArrayList<Integer>();
arr1.add(1);
System.out.println(arr1.get(0)); ArrayList<Object> arr3 = new ArrayList<Object>();
arr3.add("abc");
System.out.println(arr3.get(0)); ArrayList<Test3> arr4 = new ArrayList<Test3>();
arr4.add(new Test3());
System.out.println(arr4.get(0)); ArrayList arr5 = new ArrayList();
arr5.add("abc");
System.out.println(arr5.get(0)); ArrayList<String> arr2 = new ArrayList<String>();
arr2.add("abc");
System.out.println(arr2.get(0));
}public static void main(java.lang.String[]) throws java.lang.Exception;
Code:
0: new #2; //class java/util/ArrayList
3: dup
4: invokespecial #3; //Method java/util/ArrayList."<init>":()V
7: astore_1
8: aload_1
9: iconst_1
10: invokestatic #4; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Int
eger;
13: invokevirtual #5; //Method java/util/ArrayList.add:(Ljava/lang/Object;
)Z
16: pop
17: getstatic #6; //Field java/lang/System.out:Ljava/io/PrintStream;
20: aload_1
21: iconst_0
22: invokevirtual #7; //Method java/util/ArrayList.get:(I)Ljava/lang/Objec
t;
25: invokevirtual #8; //Method java/io/PrintStream.println:(Ljava/lang/Obj
ect;)V
28: new #2; //class java/util/ArrayList
31: dup
32: invokespecial #3; //Method java/util/ArrayList."<init>":()V
35: astore_2
36: aload_2
37: ldc #9; //String abc
39: invokevirtual #5; //Method java/util/ArrayList.add:(Ljava/lang/Object;
)Z
42: pop
43: getstatic #6; //Field java/lang/System.out:Ljava/io/PrintStream;
46: aload_2
47: iconst_0
48: invokevirtual #7; //Method java/util/ArrayList.get:(I)Ljava/lang/Objec
t;
51: invokevirtual #8; //Method java/io/PrintStream.println:(Ljava/lang/Obj
ect;)V
54: new #2; //class java/util/ArrayList
57: dup
58: invokespecial #3; //Method java/util/ArrayList."<init>":()V
61: astore_3
62: aload_3
63: new #10; //class Test3
66: dup
67: invokespecial #11; //Method Test3."<init>":()V
70: invokevirtual #5; //Method java/util/ArrayList.add:(Ljava/lang/Object;
)Z
73: pop
74: getstatic #6; //Field java/lang/System.out:Ljava/io/PrintStream;
77: aload_3
78: iconst_0
79: invokevirtual #7; //Method java/util/ArrayList.get:(I)Ljava/lang/Objec
t;
82: invokevirtual #8; //Method java/io/PrintStream.println:(Ljava/lang/Obj
ect;)V
85: new #2; //class java/util/ArrayList
88: dup
89: invokespecial #3; //Method java/util/ArrayList."<init>":()V
92: astore 4
94: aload 4
96: ldc #9; //String abc
98: invokevirtual #5; //Method java/util/ArrayList.add:(Ljava/lang/Object;
)Z
101: pop
102: getstatic #6; //Field java/lang/System.out:Ljava/io/PrintStream;
105: aload 4
107: iconst_0
108: invokevirtual #7; //Method java/util/ArrayList.get:(I)Ljava/lang/Objec
t;
111: invokevirtual #8; //Method java/io/PrintStream.println:(Ljava/lang/Obj
ect;)V
114: new #2; //class java/util/ArrayList
117: dup
118: invokespecial #3; //Method java/util/ArrayList."<init>":()V
121: astore 5
123: aload 5
125: ldc #9; //String abc
127: invokevirtual #5; //Method java/util/ArrayList.add:(Ljava/lang/Object;
)Z
130: pop
131: getstatic #6; //Field java/lang/System.out:Ljava/io/PrintStream;
134: aload 5
136: iconst_0
137: invokevirtual #7; //Method java/util/ArrayList.get:(I)Ljava/lang/Objec
t;
140: checkcast #12; //class java/lang/String
143: invokevirtual #13; //Method java/io/PrintStream.println:(Ljava/lang/St
ring;)V
146: return}字节码不一样。
当ArrayList<String>的时候,字节码多了checkcast #12; //class java/lang/String