Java 泛型 : Is any meta information about the generic type preserved at runtime as well?

标签 java generics dependency-injection guice guice-3

背景

我对 Java 泛型的理解是它完全是一个编译时特性(主要关注类型安全检查)。 任何泛型类的类型信息在运行时都会丢失(类型删除)。

不过,我看到许多框架似乎也在运行时利用类型信息。例如,google guice Providers . guice 提供程序可以在运行时实例化并提供其泛型类型的新实例。

class Container
{
     @Inject   
     public Container(Provider<Content> contentProvider)
     {
     //This works at Runtime... but How ??? 
     //When type's are not even preserved at runtime, how does the Provider knows it has to instantiate an object of type 'Content' 
     Content content = contentProvider.get();   
     }
}

问题

  1. 是否有任何与在运行时保留的泛型类型相关的信息。 ? 如果 ,什么?。 如果 ,那么像 google guice 这样的库如何在内部运作(以上示例)

  2. 除了编译时安全之外,泛型还有其他意义吗?如,是否有任何用例(除了确保编译时安全)可以使用泛型获得优势?

最佳答案

当然支持类泛型的信息。

换句话说:当您反编译 ArrayList.class 时,您会发现有关此类允许一个泛型类型参数这一事实的提示。换句话说:类文件包含 信息。使用反射可以在运行时检查此元信息。

但是当你有另一个使用一些 List<Integer> 的类时object - 那么你在编译类中找不到关于“list uses an Integer”的信息 - 除非你使用一些特定的模式,如概述here例如。

所以答案基本上是:对于几乎所有与实际相关的用例,“泛型”只是编译时

例子:

public class GenericsExample<T> {
  private T member;   
  public T foo(T bar) {
     return member;
  }
}

现在运行:javap -p -c GenericsExample

Compiled from "GenericsExample.java"
public class GenericsExample<T> {
  private T member;

  public GenericsExample();
    Code:
       0: aload_0       
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return        

  public T foo(T);
    Code:
       0: aload_0       
       1: getfield      #2                  // Field member:Ljava/lang/Object;
       4: areturn       
}

如您所见,反编译器知道该类使用泛型类型 T。有关更多详细信息,请参见 herethere .

关于Java 泛型 : Is any meta information about the generic type preserved at runtime as well?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45802927/

相关文章:

scala 类使用泛型扩展特征,泛型是字段的一种类型

c# - 具有约定的内置依赖注入(inject)

Spring - 我应该使用@Bean 还是@Component?

winforms - Ninject for winforms - 我的架构是否使其变得毫无用处?

java - 如何获取子 div id,它们直接是一个父 div 下的 child ?

java - 如何在Windows平台上更新Weblogic和JDK?

java - 获取选定的菜单项并在框架上显示相应的项目

java - 如何在 Java 中将二进制数据转换为字符串并返回?

java - 一般应用枚举成员或方法

java - 映射到实现接口(interface)的类