Java 类型擦除的工作原理

Java 类型擦除的工作原理,java,generics,jvm,kotlin,Java,Generics,Jvm,Kotlin,我正在研究创建代理对象的库是如何工作的,特别是我想了解它们是如何从声明的方法中获取类型的。例如,Android流行库-改装: interface MyService { @GET("path") Call<MyData> getData(); } 打印原始AbstractList,而此代码 System.out.println(new ArrayList<Integer>() { }.getClass().getGenericSuperclass())

我正在研究创建代理对象的库是如何工作的,特别是我想了解它们是如何从声明的方法中获取类型的。例如,Android流行库-改装:

interface MyService {

    @GET("path")
    Call<MyData> getData();
}
打印原始
AbstractList
,而此代码

System.out.println(new ArrayList<Integer>() { }.getClass().getGenericSuperclass());
System.out.println(新的ArrayList(){}.getClass().getGenericSuperclass());
打印
ArrayList

这并不是让我困惑的最后一件事。在Kotlin中,有一些具体化的泛型,这些泛型看起来像是编译时的黑客,但我们可以很容易地从泛型中获得类:

inline fun <reified T> test() {
    print(T::class)
}
inlinefun测试(){
打印(T::类)
}
现在我完全搞不懂类型擦除机制

  • 有人能解释一下,为什么它有时保存信息,有时不保存
  • 为什么泛型不能在Java中以正常的方式实现?是的,我读到它可能会打破与以前版本的兼容性,但我想了解它是如何做到的。为什么泛型返回类型除了
    newarraylist
    之外不破坏任何东西
  • 为什么匿名类持有泛型类型而不被类型擦除 更新: 4.具体化泛型在Kotlin中是如何工作的?为什么这样酷的东西不能在Java中实现

    非常清楚地解释了具体化泛型是如何工作的@Mibac

    您只能将reified与内联函数结合使用。这样的 函数使编译器将函数的字节码复制到每个 正在使用功能的位置(正在使用功能 “内联”)。当调用具有具体化类型的内联函数时 编译器知道用作类型参数的实际类型并修改 生成的字节码直接使用相应的类。 因此,如果类型为 参数是字符串,在字节码和运行时

    有人能解释一下,为什么它有时保存信息,有时不保存

    在jvm级别,有一个:

    记录类、接口、构造函数、方法或字段的签名(§4.7.9.1),该类、接口、构造函数、方法或字段在Java编程语言中的声明使用类型变量或参数化类型

    您可能想要它的原因之一是,例如,编译器需要知道来自预编译的
    some.class
    (来自第三方
    some.jar
    )的
    some\u方法的实际参数类型。在此场景中,假设方法采用
    对象
    可能会违反编译
    某些.class
    时使用的假设,并且不能以类型安全的方式调用
    某些方法

    为什么匿名类持有泛型类型而不被类型擦除

    当你打电话时:

    System.out.println(new ArrayList<Integer>().getClass().getGenericSuperclass());
    
    System.out.println(新的ArrayList().getClass().getGenericSuperclass());
    
    。。。没有任何东西是根据jvm类定义的,但是:

    System.out.println(new ArrayList<Integer>() { }.getClass().getGenericSuperclass());
    
    System.out.println(新的ArrayList(){}.getClass().getGenericSuperclass());
    
    。。。实际上在jvm级别上定义类,在java语言级别上定义albiet anonymous

    这就是为什么反射对这些情况给出不同结果的原因

    为什么泛型不能在Java中以正常的方式实现?是的,我读到它可能会打破与以前版本的兼容性,但我想了解它是如何做到的。为什么泛型返回类型除了new ArrayList之外不破坏任何东西

    具体化泛型在Kotlin中是如何工作的?为什么这样酷的东西不能在Java中实现

    我不认为你能给出客观的答案,而不是基于这些观点。此外,我建议你们要么分开,要么缩小问题的范围

    System.out.println(new ArrayList<Integer>().getClass().getGenericSuperclass());
    
    System.out.println(new ArrayList<Integer>() { }.getClass().getGenericSuperclass());