黑马程序员技术交流社区
标题:
关于泛型和反射的一个问题
[打印本页]
作者:
jaijaiok
时间:
2013-12-9 22:40
标题:
关于泛型和反射的一个问题
有如下代码片段
1 ArrayList<String> collection2 = new ArrayList<String>();
2 collection2.add("abc");
3 collection2.getClass().getMethod("add", Object.class).invoke(collection2,
4 new Integer(48));
5 Object obj=collection2.get(1);
6 System.out.println(obj.getClass().getName());
7 // System.out.println(collection2.get(1).getClass().getName());
复制代码
第7行不注释掉时会出现ClassCastException,但是如果按照第5、6行这样写又可以顺利通过编译并正常显示java.lang.Integer
在此想请教各位java大神这样分开写和合着写的区别何在,以及为什么分开写就不会出现异常。
先谢谢各位大神,纠结了很久了,还是想不通
作者:
衣带赞
时间:
2013-12-10 01:28
这个问题我之前也问过,不过没人能回答出来。不过可以肯定的是,只有在String类中才会出现这个问题,当你把泛型定义为Integer时,就没有问题了。为了验证,我还自己创建了一个Person类扔到泛型里面去,也不会出现这个异常。
据我估计,这是String类中一个很特别的地方。这个问题在编译时是没问题的,在运行时发生异常。那么就是在打印这个地方出了问题。我估计在打印一个被编译器认定为了String类的时候,会检测它是否为String类,如不是,发生异常。当打印一个不是String类的其它类时,调用被打印类的toString()方法。只有这样才能解释为什么此处会发生异常。我例子的代码:
import java.util.ArrayList;
public class Test3 {
public static void main(String[] args) throws Exception{
//泛型限定为Integer,加入String类,无异常
ArrayList<Integer> al1 = new ArrayList<Integer>();
al1.add(123);
al1.getClass().getMethod("add", Object.class).invoke(al1, "gg");
System.out.println(al1.get(1));
//泛型限定为Person,加入String类,无异常
ArrayList<Person> al3 = new ArrayList<Person>();
al3.add(new Person());
al3.getClass().getMethod("add",Object.class).invoke(al3,"来个String试试");
System.out.println(al3.get(1));
//泛型限定为String,加入Integer类,出现java.lang.ClassCastException
ArrayList<String> al2 = new ArrayList<String>();
al2.add("abc");
al2.getClass().getMethod("add", Object.class).invoke(al2,123);
System.out.println(al2.get(1));
}
}
class Person
{
public String toString(){
return "自己创建一个类试试看";
}
}
复制代码
所以,你那个代码只要改一个地方就可以了
System.out.println(collection2.get(1).getClass().getName());
改为
System.out.println(((Object)collection2.get(1)).getClass().getName());
即可
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2