当前位置: 首页 > 面试题库 >

Java泛型:是否也可以在运行时保留有关泛型类型的任何元信息?

松俊美
2023-03-14
问题内容

背景

我对 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. 是否还有与泛型类型相关的信息,这些信息也会在运行时保留。? 如果 ,那 什么? 如果为 no ,那么google guice之类的库如何在内部运行(上述示例

  2. 除了编译时安全以外,泛型还有更多的东西吗?像在一样,是否有任何用例(除了确保编译时安全性之外)都可以使用泛型获得优势?


问题答案:

当然,信息的一个类 通用的支持。

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

但是,当您有另一个使用某些List<Integer>对象的类时-则在已编译的类中找不到有关该“列表使用整数”的信息-
除非您使用某些特定的模式(例如此处概述)。

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

例:

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。



 类似资料:
  • 问题内容: 我正在尝试基于指定的泛型类型进行强制转换和/或生成一个变量。我知道并没有快速的类型擦除,但是除了泛型的指定条件(例如符合基类)外,泛型似乎并没有保留类型。看来我可以强制转换或初始化的只是基类。更奇怪的是,当我在调试器中时,泛型似乎对正确的类具有RawPointer,甚至变量看起来都像是正确的类型: 编辑: 从Xcode 6.1开始,这仍然是一个问题(简化的代码由Gregory Higl

  • 如何获取这个类的类型?对于上下文,我使用ModelMapper,我需要类类型T从S转换为T。 背景: 我已经尝试了N种方法,其中我放置了“//一些方法来获取类型”,但没有任何效果。例如: 或

  • 如果我们提供足够的泛型信息,像Jackson这样的库可以从JSON创建对象。 在杰克逊,我们可以 在这种情况下,我们应该得到 在这种情况下,我们应该得到 在这种情况下,我们应该得到 为了进一步澄清,我希望在不创建任何其他类的情况下获取类型信息,并且这些信息应该传递给序列化程序,即我不希望更改类似于的序列化程序方法签名。我们可以创建任意多的helper类,也可以强制从某个超类扩展有效负载类(超类可以

  • 问题内容: 好的,因此,我正在设置自己的XML序列化(我知道那里还有其他东西,甚至Java中内置了一些东西,但是我自己学习来做,因为可以使用它非常棒)。我已经序列化了。我目前正在进行反序列化(读取XML文件并基于文件中的数据组装对象),并且在设置通用类型时遇到问题。经过广泛研究,我弄清楚了如何获取类的泛型类型,以便在序列化时可以编写它们,但是我不知道如何执行此操作: 我已经在C#中看到了一些答案,

  • 问题内容: 我有一个代表文本片段的泛型类。该文本片段可能具有多种不同模式(突出显示的不同类型)中的任何一种。这些模式用枚举表示。每个项目的Enum可能不同,但是它必须实现一个接口,该接口提供了一种将其中两个结合的方法(可以突出显示并加粗显示)。所以我有一个界面: 然后我的TextFragment是文本字符串和模式的容器。但是当我尝试声明该类时: 我收到以下错误: 令牌“扩展”的语法错误,预期 根据

  • 我有一个父类来处理我所有的自定义异常,父母异常。我希望所有的子异常都有一个方法来向异常添加消息。为了做到这一点,我创建了一个泛型方法,在向其添加消息后返回泛型类型的对象。我在父类方法中使用来添加消息,然后返回,但是由于该方法返回泛型类型,所以我将其转换为泛型类型T。这似乎是可行的,但是给出了警告。我的代码如下: 该行给出的警告是。这种方法似乎确实如预期的那样有效,所以我并不担心,但我想更好地理解为