锁定老帖子 主题:泛型理解上的一个问题
该帖已经被评为隐藏帖
|
|
---|---|
作者 | 正文 |
发表时间:2010-11-08
System.out.println("arr2中第0个元素是:"+arr2.get(0));
|
|
返回顶楼 | |
发表时间:2010-11-08
这应该是一个println重载的问题,并不是反射引起的classcastexception,
System.out.println(arr1.get(1)); //此时调用的是println(Object x)的方法,看代码: public void println(Object x) { String s = String.valueOf(x); synchronized (this) { print(s); newLine(); },这里会显示的调用valueOf()方法,所以在print的时候,都会调用该对象自身的toString,不会出异常。而System.out.println(arr2.get(1));此时arr2.get(1)的编译类型是String,所以调用的是println(String x),此时就不会做toString的操作,直接作为了String对象,所以编译器会产生checkcast语句,看arr2.get(1)能否转换为String,而此时arr2.get(1)是Integer,做类型转换的时候便会报错。 |
|
返回顶楼 | |
发表时间:2010-11-08
最后修改:2010-11-08
先看看啊
|
|
返回顶楼 | |
发表时间:2010-11-08
arr2.add("why");
arr2.getClass().getMethod("add", Object.class).invoke(arr2, 33); Object obj2 = arr2.get(1); // Class clazz2 = obj2.getClass(); System.out.println(obj2); //#1 System.out.println(arr2.get(1));//#2 #1 是可以的, 但是#2是不能运行的。 按F3进入#1 println(),调用的是println(Object), 而#2调用的是println(String), 那这个问题就解决了,事实上正如yunzhiyifeng所说的,这个是println()的重载造成的。 |
|
返回顶楼 | |
发表时间:2010-11-08
forestking 写道 arr2.add("why");
arr2.getClass().getMethod("add", Object.class).invoke(arr2, 33); Object obj2 = arr2.get(1); // Class clazz2 = obj2.getClass(); System.out.println(obj2); //#1 System.out.println(arr2.get(1));//#2 #1 是可以的, 但是#2是不能运行的。 按F3进入#1 println(),调用的是println(Object), 而#2调用的是println(String), 那这个问题就解决了,事实上正如yunzhiyifeng所说的,这个是println()的重载造成的。 谢谢分析,想问下: 从哪得知arr2.get(1)是String? 如果分析正确,那arr1.get(1)应该是print(Integer),作为String类型调用它怎么打印不报异常呢?而且arr1.get(1)还打印出来了? |
|
返回顶楼 | |
发表时间:2010-11-08
最后修改:2010-11-08
按住ctrl键,点击第一个System.out.println(arr1.get(1));发现进入的是
public void println(Object x) { synchronized (this) { print(x); newLine(); } } 点击第二个System.out.println(arr2.get(1));发现进入的是 public void println(String x) { synchronized (this) { print(x); newLine(); } } 因为定义ArrayList的时候已经知道arr.get()的返回值类型,所以还是楼上所说的重载问题造成的 |
|
返回顶楼 | |
发表时间:2010-11-08
悲剧了 写道 forestking 写道 arr2.add("why");
arr2.getClass().getMethod("add", Object.class).invoke(arr2, 33); Object obj2 = arr2.get(1); // Class clazz2 = obj2.getClass(); System.out.println(obj2); //#1 System.out.println(arr2.get(1));//#2 #1 是可以的, 但是#2是不能运行的。 按F3进入#1 println(),调用的是println(Object), 而#2调用的是println(String), 那这个问题就解决了,事实上正如yunzhiyifeng所说的,这个是println()的重载造成的。 谢谢分析,想问下: 从哪得知arr2.get(1)是String? 如果分析正确,那arr1.get(1)应该是print(Integer),作为String类型调用它怎么打印不报异常呢?而且arr1.get(1)还打印出来了? System.out.println() 是没有Integer作为参数的重载的, System.out.println(new Integer(2)) 事实上也是调用的println(Object). |
|
返回顶楼 | |
发表时间:2010-11-08
qianhd 写道 你们的瞎猜真没创意
改成 ArrayList arr2=new ArrayList<String>(); 就不会有异常 至于为什么 回去慢慢想 这根本就不是泛型了: ArrayList arr2=new ArrayList<String>(); arr2.add(123); 不会出错的! |
|
返回顶楼 | |
发表时间:2010-11-08
最后一句改成
System.out.println((Object)arr2.get(1)); 就不会报错,正常打印出来33了。 所以说,编译器其实是对你最后一句print语句进行了优化而已,你可以看看jdk源码里面println的实现。并没有所谓的println(Integer x)这种实现,所有对象类型的都是调用println(Object x),除了String类型有自己的实现println(String x)。 |
|
返回顶楼 | |
发表时间:2010-11-08
jwnest 写道 最后一句改成
System.out.println((Object)arr2.get(1)); 就不会报错,正常打印出来33了。 所以说,编译器其实是对你最后一句print语句进行了优化而已,你可以看看jdk源码里面println的实现。并没有所谓的println(Integer x)这种实现,所有对象类型的都是调用println(Object x),除了String类型有自己的实现println(String x)。 谢谢分析! 总算弄明白了,原来是这么个原因. 看来可以结贴了. |
|
返回顶楼 | |