Java类型擦除擦除我的泛型类型? [英] does Java type erasure erase my generic type?

查看:160
本文介绍了Java类型擦除擦除我的泛型类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我认为java擦除抹去了编译时的泛型类型,但是当我自己测试时,我意识到有一些关于Bytecode中泛型类型的信息。



这里是我的测试:

我写了2个类:

$ $ p $ import java.util中*。
public class Test {
List integerList;
}

  import java.util。*; 
public class Test {
List< Integer> integerList;

$ / code>

我编译了这两个类,并且在泛型类中的某处我看到了这一行

  integerList {blah blah} Ljava / util / List; {blah blah} 
签名{blah blah}%Ljava / util / List< Ljava / lang / Integer;>; {blah blah}< init>

在非泛型类中:

  integerList {blah blah} Ljava / util / List; {blah blah}< init> 

很显然,我在字节码里面有通用信息,所以这个删除的东西是什么?

解决方案

一些通用类型信息存储在 Signature 属性中。请参阅 JLS 4.8 4.6 JVM规范4.3.4 。阅读此处


关于Java中泛型最常见的抱怨是它们没有被通用化 - 在运行时没有办法知道 List< String> 是与 List< Long> 不同。我已经习惯了这一点,我很惊讶地发现Neil Gafter在超类型令牌上的工作。 事实证明,虽然JVM不会跟踪泛型类实例的实际类型参数,但它会跟踪泛型类子类的实际类型参数。换句话说,当新的<$在运行时,如果一个类扩展了,ArrayList< String>()实际上只是一个新的 ArrayList() > ArrayList< String> ,那么JVM知道 String 是 List 的类型参数。


Neal Gafter的博客


I've thought java erasure wipes generic types out in compile time however when i test it by myself i realized there are some information about generic types in Bytecode.

here is my test :

i wrote 2 classes:

import java.util.*;
public class Test {
    List integerList;
} 

and

import java.util.*;
public class Test {
    List<Integer> integerList;
} 

i compiled both classes and somewhere in generic class i saw this line

integerList{blah blah}Ljava/util/List;{blah blah}
Signature{blah blah}%Ljava/util/List<Ljava/lang/Integer;>;{blah blah}<init>

in non generic class :

integerList{blah blah}Ljava/util/List;{blah blah}<init>

so obviously i have generic information inside bytecode so what is this erasure thing ??

解决方案

Some Generic type information is stored in Signature attributes . Refer JLS 4.8 and 4.6 and JVM spec 4.3.4. Read here:

Probably the most common complaint about generics in Java is that they are not reified - there is not a way to know at runtime that a List<String> is any different from a List<Long>. I've gotten so used to this that I was quite surprised to run across Neil Gafter's work on Super Type Tokens. It turns out that while the JVM will not track the actual type arguments for instances of a generic class, it does track the actual type arguments for subclasses of generic classes. In other words, while a new ArrayList<String>() is really just a new ArrayList() at runtime, if a class extends ArrayList<String>, then the JVM knows that String is the actual type argument for List's type parameter.

and Neal Gafter's blog.

这篇关于Java类型擦除擦除我的泛型类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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