论坛首页 Java企业应用论坛

诡异代码,麻烦各位大牛看下【泛型】

浏览 11113 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-11-29  
请各位先猜下结果,然后执行代码
代码一:
import java.util.ArrayList;
import java.util.List;

public class Test004 {
	public static void main(String[] args) {
		List lst = new ArrayList<String>();
		lst.add(1);
		lst.add("Test004");
		List<Integer> ls = lst;
		ls.add(2);
		for (int i = 0; i < ls.size(); i++) {
			System.out.println(ls.get(i));
		}
	}
}

代码二:
import java.util.ArrayList;
import java.util.List;

public class Test005 {
	public static void main(String[] args) {
		List lst = new ArrayList<String>();
		lst.add(1);
		lst.add("Test004");
		List<String> ls = lst;
		ls.add("Test0041");
		for (int i = 0; i < ls.size(); i++) {
			System.out.println(ls.get(i));
		}
	}
}
   发表时间:2011-11-29  
有什么诡异,代码"欺骗"了编译器而已
List lst = new ArrayList<String>();这句List改List<String> lst这样,编译就不让过了,就不会发生所谓的类型转换错误  
0 请登录后投票
   发表时间:2011-11-30  
http://jjhou.boolan.com/javatwo-2004-GP-in-jdk15.pdf
0 请登录后投票
   发表时间:2011-11-30  

错误的代码说明了泛型存在的理由
同时非必要尽量不要使用auto boxing/unboxing

0 请登录后投票
   发表时间:2011-11-30  
PrintStream类中有println(Object x), println(String x),但是没有println(Integer x)

List<Integer> ls = lst;
执行的是println(Object x),先执行String.valueOf(x), 然后再用print(String)打印,所以不会出错。

List<String> ls = lst; 
执行的是println(String x)方法,Integer转String出错。
4 请登录后投票
   发表时间:2011-11-30  
楼上正解,貌似和泛型无关
0 请登录后投票
   发表时间:2011-11-30  
两个get(i)出来的都是Object。List<Integer>   List<String> 两个ls都是指向了之前的地址而已

引用
PrintStream类中有println(Object x), println(String x),但是没有println(Integer x)

List<Integer> ls = lst;
执行的是println(Object x),先执行String.valueOf(x), 然后再用print(String)打印,所以不会出错。

List<String> ls = lst; 
执行的是println(String x)方法,Integer转String出错。

是正解
1 请登录后投票
   发表时间:2011-12-01  
 public void println(String x) {
	synchronized (this) {
	    print(x);
	    newLine();
	}
    }

    /**
     * Prints an Object and then terminate the line.  This method calls
     * at first String.valueOf(x) to get the printed object's string value,
     * then behaves as
     * though it invokes <code>{@link #print(String)}</code> and then
     * <code>{@link #println()}</code>.
     *
     * @param x  The <code>Object</code> to be printed.
     */
    public void println(Object x) {
        String s = String.valueOf(x);
        synchronized (this) {
            print(s);
            newLine();
        }
    }

看看源代码就清楚
0 请登录后投票
   发表时间:2011-12-01  
泛型擦除+转换异常而已。。

java的泛型是伪泛型。只是编译的时候用以检查而已。。
当需要输出的时候。会强转为需要的类型。
如果类型不匹配转换不了。则会报转换异常
0 请登录后投票
   发表时间:2011-12-01  
编译器级别的东西,如果你想看到底怎么回事,看class代码就ok了
0 请登录后投票
论坛首页 Java企业应用版

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