Java泛型:在运行时是否还保留了有关泛型类型的元信息? [英] Java Generics : Is any meta information about the generic type preserved at runtime as well?

查看:410
本文介绍了Java泛型:在运行时是否还保留了有关泛型类型的元信息?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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


尽管如此,我还是发现许多框架 似乎 可以在运行时利用类型信息。例如,google guice 供应商。 Guice提供程序可以在运行时实例化并提供它的通用类型的新实例。

  class Container 
{
@Inject
public Container(Provider< Content> contentProvider)
{
//这在运行时工作...但是如何?
//当运行时类型不被保存时,Provider如何知道它必须实例化一个类型为'Content'的对象
Content content = contentProvider.get();
}
}

问题


  1. 是否有与在运行时保存的泛型类型相关的任何信息。 ? 如果 ,什么? 如果 不是,与Google Guice之类的库如何在内部运作(上例)

  2. 更多泛型,而不仅仅是编译时间安全?如有,有什么用例(除确保编译时安全性)哪里可以利用泛型优势? em> generic是支持的。换句话说:当你反编译ArrayList.class时,你会发现这个类允许一个泛型类型参数的提示。换句话说:类文件包含信息。使用反射可以在运行时检查这个元信息。



    但是当你有另一个类使用 List< Integer> object - 那么您在编译的类中找不到有关list使用整数的信息 - 除非您使用某些特定模式,如 。实际相关的情况下,泛型只是编译时间



    示例:

      public class GenericsExample< T> {
    私人T会员;
    public T foo(T吧){
    return member;




    $ b现在运行:javap -p -c GenericsExample
    p>

     编译自GenericsExample.java
    public class GenericsExample< T> {
    私人T会员;

    public GenericsExample();
    代码:
    0:aload_0
    1:invokespecial#1 //方法java / lang / Object。< init>:()V
    4:return

    public T foo(T);
    代码:
    0:aload_0
    1:getfield#2 //字段成员:Ljava / lang / Object;
    4:areturn
    }

    正如你所看到的,反编译器知道类使用该泛型类型T.有关更多详细信息,请参阅此处其中


    Background

    My understanding of Java generics is it being completely a compile time feature (mainly focusing on type safety checks). The type information for any generic class is lost at runtime (type erasure).

    Still, i see many frameworks seem to leverage the type information at runtime as well. For example, google guice Providers. The guice provider can instantiate and provide new instances of it's generic type at runtime.

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

    Question

    1. Is there any information related to generic types which is preserved at runtime as well. ? If yes, what ?. If no, than how does libraries like google guice operate internally (Above example)

    2. Is there more to generics than just compile time safety ? As in, is there any use-case (other than ensuring compile time safety) where one would get advantage using generics ?

    解决方案

    Of course the information that a class is generic is supported.

    In other words: when you decompile ArrayList.class you will find hints about the fact that this class allows for one generic type parameter. In other words: class files contain meta information. And using reflection it is possible to inspect this meta information at runtime.

    But when you have another class that uses some List<Integer> object - then you do not find information about that "list uses an Integer" in the compiled class - unless you use some specific patterns, as outlined here for example.

    So the answer is basically: for almost all use cases of practical relevance, "generics" are compile time only.

    Example:

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

    Now run: 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       
    }
    

    As you can see the decompiler understands that the class uses that generic type T. For more details see here or there.

    这篇关于Java泛型:在运行时是否还保留了有关泛型类型的元信息?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆