了解Java中的类型擦除

了解Java中的类型擦除,java,type-erasure,Java,Type Erasure,如果没有类型擦除,如何实现泛型?据我所知,如果我有类Foo,T基本上被对象替换,编译器只有元数据可以帮助它将其转换为正确的参数化类型 但是,如果实现了具体化,那么T将是实际的参数化类型(与对象相反)。。。但是我不明白编译器如何才能判断new t()是否是有效的调用(即,t可能没有无参数构造函数)。在Java中,构造函数不是由子类继承的,因此只要给定的参数化类型t不能缩小到特定类型,您将无法运行newt(),因为Java是静态类型的,无论是否发生具体化。然而,使用new实例化只是使用类的一种情况

如果没有类型擦除,如何实现泛型?据我所知,如果我有
类Foo
T
基本上被
对象替换,编译器只有元数据可以帮助它将其转换为正确的参数化类型


但是,如果实现了具体化,那么
T
将是实际的参数化类型(与对象相反)。。。但是我不明白编译器如何才能判断
new t()
是否是有效的调用(即,t可能没有无参数构造函数)。

在Java中,构造函数不是由子类继承的,因此只要给定的参数化类型
t
不能缩小到特定类型,您将无法运行
newt()
,因为Java是静态类型的,无论是否发生具体化。然而,使用
new
实例化只是使用类的一种情况

瞬间 对我来说,不被擦除的泛型最明显的用途是能够在
instanceof
表达式中使用
t

class Box<T> {
   public boolean isInst(Object obj) {
      return obj instanceof T;
   }
}
有了这些定义,下面的代码

class Box<T extends Parent> {

   void test() { T.doSomething(); }

   public static void main(String...args) {
      Box<Parent> parentBox = new Box<>();
      Box<Child> childBox = new Box<>();

      parentBox.test();
      childBox.test();
   }
}
而是打印:

Parent
Parent
这是因为
T
通过擦除变成了
Parent

遗产 泛型继承(听起来很奇怪)可能(可能)存在:

公共类GenericType{
公共类内部扩展T{}
公共静态void main(字符串…参数){
GenericType.Inner obj=新建GenericType().new Inner();
System.out.println(MyClass的obj实例);//打印为true
}
}

确切地说,这就是为什么在通过反射调用随机构造函数时会出现异常的原因。此外,您可以指定通过编译器在此处抱怨的方式缩小类型定义的范围:
类测试{void t(ts){new t();}}
基本语法如下:
t newT=(t)s.getClass().getConstructor().newInstance()不知道如何避免未经检查的强制转换警告,尽管无法使用泛型避免类型擦除。他们就是这样工作的。但是,通常不会将完全不同的类传递给泛型类。
new T()
限制与类型擦除没有直接关系。如果您在编译时不知道
t
,那么无论
new t()
在运行时是否可用,您都不知道它是否有效。C#使用
求解,其中T:new()
和Java理论上可以做类似的事情。
Parent
Child
Parent
Parent
public class GenericType<T> {
   public class Inner extends T {   }

   public static void main(String...args) {
      GenericType<MyClass>.Inner obj = new GenericType<MyClass>().new Inner();
      System.out.println(obj instanceof MyClass); // Prints true
   }
}