java – 类型擦除的工作原理

前端之家收集整理的这篇文章主要介绍了java – 类型擦除的工作原理前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

我正在调查创建代理对象的库是如何工作的,特别是我想了解它们如何从声明的方法获取类型.例如Android的流行库 – Retrofit:

interface MyService {

    @GET("path")
    Call

我很困惑 – 如何才能从这个界面获得正确的MyData类而不是原始对象?我的理解类型擦除的原因将删除放置在通用大括号内的任何信息.

我写了一些测试代码,令我惊讶的是从这样的代码获取类型真的很容易:

@org.junit.Test
public void run() {
    Method[] methods = Test.class.getDeclaredMethods();
    Method testMethod = methods[0];
    System.out.println(testMethod.getReturnType());
    ParameterizedType genericType = ((ParameterizedType) testMethod.getGenericReturnType());
    Class

它看起来有点脏,但它工作并打印整数.这意味着我们在运行时有类型.此外,我已经阅读了有关匿名类的另一个脏技巧:

System.out.println(new ArrayList

打印raw AbstractList< E>而这段代码

System.out.println(new ArrayList

打印ArrayList< Integer>.

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

inline fun 

而现在我完全混淆了类型擦除机制.

>有人可以解释一下,为什么有时它会保存信息而有时却没有?
>为什么在Java中没有以正常方式实现泛型?是的,我读到它可能会破坏先前版本的兼容性,但我想了解如何.除了新的ArrayList< Integer>之外,为什么泛型返回类型不会破坏任何东西?
>为什么匿名类包含泛型类型而不是类型擦除?

更新:
4.如何在Kotlin中使用具体的泛型以及为什么这样的酷事不能用Java实现?

Here很清楚地解释了具体的仿制药是如何工作的. @Mibac

You can only use reified in combination with an inline function. Such
a function makes the compiler copy the function’s bytecode to every
place where the function is being used (the function is being
“inlined”). When you call an inline function with reified type,the
compiler knows the actual type used as a type argument and modifies
the generated bytecode to use the corresponding class directly.
Therefore calls like myVar is T become myVar is String,if the type
argument were String,in the bytecode and at runtime.

最佳答案

Can someone explain,why sometimes it holds information and sometimes doesn’t?

在jvm级别上有一个Signature attribute

records a signature (§4.7.9.1) for a class,interface,constructor,method,or field whose declaration in the Java programming language uses type variables or parameterized types.

您可能希望拥有它的原因之一是,例如,编译器需要知道来自预编译some.class(来自第三方some.jar)的some_method的实际参数类型.在这种情况下,假设方法采用Object可能违反编译some.class的假设,并且您不能以类型安全的方式调用some_method.

Why do anonymous classes hold generic type and are not type erasured?

你打电话的时候:

System.out.println(new ArrayList

……根据jvm类没有任何定义,而这个:

System.out.println(new ArrayList

…实际上在jvm级别上定义了类,在java laguage级别上定义了albiet匿名.

这就是为什么反射为这些情况提供不同结果的原因.

Why generics isn’t implemented in normal way in Java? Yes,I read that it could break compabillity with prevIoUs versions,but I want to understand how. Why does generic return type not break anything but new ArrayListdoes?

How do reified generics works in Kotlin and why such cool thing can’t be implemented in Java?

我不认为你能给出客观的答案,而不是基于意见的答案.此外,我建议拆分或缩小问题的范围.

猜你在找的Java相关文章