类型擦除:Java与C#

可能重复:
C#vs Javagenerics

Java使用Type erasureC#在运行时保留类型信息,这种设计语言行为的实际差异是什么?

类型擦除存在很多问题。 它带回了不好的回忆。 我从1.6开始就没用过Java,所以这可能已经过时了,但有些事我记得:

  1. 你不能创建一个新的T(或做任何需要知道T实际是什么类型的东西)
  2. 通用列表无法创建T数组
  3. 你不能在Java的generics中使用int,float等
    1. 这有性能和内存的影响,因为你总是必须使用堆版本(整数等)
  4. 您不能使用两个不同的Ts实现通用接口,例如, class c implements IComparable, IComparable是不可能的。
    1. 更实际的是,您不能使用不同的generics类型重载方法,例如通过接收ListList等。 例如, Java – 如何处理构造函数中的类型擦除?
  5. 一切都是通过铸造和拳击完成的

这是一个只有在运行时保留类型信息时才有可能的例子:

 public string DoSomething() { return typeof(T).Name; } 

你在Java中最接近的是:

 public  string DoSomething(Class theClass) { return theClass.getName(); } 

由于类型擦除而在Java中发生的事情是创建称为“桥接方法”的合成方法。

当Java尝试编译扩展参数化类或实现参数化接口的类或接口时,通常会发生这种情况。 在这种情况下,Java编译器可能需要创建一个合成方法(桥接方法)作为类型擦除过程的一部分,它出现在堆栈跟踪中。

编译器执行此操作以在类型擦除过程之后保留generics类型的多态性。

Java的文档有一个例子 。