Java:尝试使用泛型

时间:2013-08-07 11:50:44

标签: java generics

最后,我尝试了一些仿制药。我想出了这段代码:

public class Test {

    static <T> void f(T x) {
        x = (T) (Integer) 1234;
        System.out.println(x);
    }

    public static void main(String[] args) {
        f("a");
        f(1);
        f('a');
        f(1.5);
        f(new LinkedList<String>());
        f(new HashMap<String, String>());
    }
}

我跑了这个并得到了这个输出:

1234
1234
1234
1234
1234
1234

没有例外!怎么可能?

2 个答案:

答案 0 :(得分:37)

这是因为type erasure(已经写了很多关于此的内容,只是google这个术语)。在将f编译为字节代码后,该方法可能如下所示:

static void f(Object x) {
    x = (Object) (Integer) 1234;
    System.out.println(x);
}

因此System.out.println只会调用对象toString上的x方法 - 在您的情况下,它是Integer.toString()

答案 1 :(得分:4)

因为类型擦除。来自Oracle's documentation

  

泛型被引入Java语言以提供更紧密的类型   在编译时检查并支持通用编程。至   实现泛型,Java编译器将类型擦除应用于:

     
      
  • 将泛型类型中的所有类型参数替换为其边界或   对象,如果类型参数是无界的。生成的字节码,   因此,只包含普通的类,接口和方法。

  •   
  • 如有必要,插入类型转换以保护类型安全。

  •   
  • 生成桥接方法以保留扩展泛型类型中的多态性。
  •   
     

类型擦除确保不会为参数化创建新类   类型;因此,泛型不会产生运行时开销。