简体   繁体   English

了解Java中的类型清除

[英]Understand Type Erasure in Java

How would one implement generics without type erasure ? 没有类型擦除的情况下如何实现泛型 As I understand it, if I have class Foo<T> , the T is replaced basically replaced with Object and the compiler only has metadata that helps it cast it to the right paramterized type. 据我了解,如果我有class Foo<T> ,则T基本上被Object取代,并且编译器仅具有帮助它将其转换为正确的参数化类型的元数据。

But, if reification was implemented, then the T would be the actual parameterized type (as opposed to Object)... But I don't understand how the compiler would then able to figure out if new T() is valid invocation (ie, T might not have a no-arg constructor). 但是,如果实现了实现,则T将是实际的参数化类型(与Object相对)...但是我不明白编译器如何才能确定new T()是否有效调用(即,则T可能没有no-arg构造函数)。

In Java specifically, constructors are not inherited by subclasses, so as long as a given parameterized type T can't be narrowed down to a specific type, you wouldn't be able to run new T() , since Java is statically typed, regardless of whether or not reification happens . 具体来说,在Java中,构造函数不会被子类继承,因此,只要无法将给定的参数化类型T缩小为特定类型,就无法运行new T() ,因为Java是静态类型的, 不管是否发生了改造 However, instantiation using new is only one case where classes are used. 但是,使用new实例化只是使用类的一种情况

Instanceof INSTANCEOF

The most obvious use to me for generics that aren't erased is being able to use T in an instanceof expression: 对于我来说,不被删除的泛型最明显的用途是能够在instanceof表达式中使用T

class Box<T> {
   public boolean isInst(Object obj) {
      return obj instanceof T;
   }
}

There's also the idea of seeing if T is a superclass or subclass of other classes, or checking equality with classes. 还有一个想法,就是查看T是其他类的超类还是子类,或者检查类的相等性。

Static Methods 静态方法

With reification, Java would be able to call static methods on T "correctly." 借助这种技术,Java可以“正确”调用T上的static方法。 Let's say we have the following classes: 假设我们有以下课程:

class Parent {
   void doSomething() { System.out.println("Parent"); }
}

class Child extends Parent {
   void doSomething() { System.out.println("Child"); }
}

With those defined, then the following code... 定义好这些之后,下面的代码...

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();
   }
}

...should print: ...应打印:

Parent
Child

but instead prints: 但改为打印:

Parent
Parent

This is because T turns into Parent by erasure. 这是因为T通过擦除变成了Parent

Inheritance 遗产

Generic inheritance (as weird as it sounds) could (probably) exist: 通用继承(听起来很奇怪)可能(可能)存在:

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
   }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM