论坛首页 Java企业应用论坛

泛型理解上的一个问题

浏览 10387 次
该帖已经被评为隐藏帖
作者 正文
   发表时间:2010-11-08  
System.out.println("arr2中第0个元素是:"+arr2.get(0));
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,做类型转换的时候便会报错。
1 请登录后投票
   发表时间:2010-11-08   最后修改:2010-11-08
先看看啊

0 请登录后投票
   发表时间: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()的重载造成的。

0 请登录后投票
   发表时间: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)还打印出来了?
0 请登录后投票
   发表时间: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()的返回值类型,所以还是楼上所说的重载问题造成的
0 请登录后投票
   发表时间: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).
0 请登录后投票
   发表时间:2010-11-08  
qianhd 写道
你们的瞎猜真没创意

改成 ArrayList arr2=new ArrayList<String>();  

就不会有异常
至于为什么 回去慢慢想

这根本就不是泛型了:
ArrayList arr2=new ArrayList<String>();  
arr2.add(123);
不会出错的!
0 请登录后投票
   发表时间:2010-11-08  
最后一句改成
System.out.println((Object)arr2.get(1));
就不会报错,正常打印出来33了。

所以说,编译器其实是对你最后一句print语句进行了优化而已,你可以看看jdk源码里面println的实现。并没有所谓的println(Integer x)这种实现,所有对象类型的都是调用println(Object x),除了String类型有自己的实现println(String x)。



1 请登录后投票
   发表时间: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)。




谢谢分析!
总算弄明白了,原来是这么个原因.
看来可以结贴了.
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics