简体   繁体   English

Java-通用类型-类型擦除

[英]Java - Generic Types - Type Erasure

I found the following question and answer on the oracle website 我在oracle网站上发现了以下问答

What is the following class converted to after type erasure? 类型擦除后,以下类转换为什么?

public class Pair<K, V> {

    public Pair(K key, V value) {
        this.key = key;
        this.value = value;
    }

    public K getKey(); { return key; }
    public V getValue(); { return value; }

    public void setKey(K key)     { this.key = key; }
    public void setValue(V value) { this.value = value; }

    private K key;
    private V value;
}

Answer: 回答:

public class Pair {

    public Pair(Object key, Object value) {
        this.key = key;
        this.value = value;
    }

    public Object getKey()   { return key; }
    public Object getValue() { return value; }

    public void setKey(Object key)     { this.key = key; }
    public void setValue(Object value) { this.value = value; }

    private Object key;
    private Object value;
}

But when i decompile the class file using JD-GUI, i still see all the generic types similar what i have in the actual source code. 但是当我使用JD-GUI反编译类文件时,我仍然看到所有通用类型与实际源代码中的相似。

Does this mean that the generic types are retained in the class file? 这是否意味着泛型类型保留在类文件中? i'm using Java 6. 我正在使用Java 6。

The decompiler version of the class using JD-GUI is as follows. 使用JD-GUI的类的反编译器版本如下。 I'm using Eclipse Helios to compile the class. 我正在使用Eclipse Helios来编译类。

public class Pair<K, V>
{
  private K key;
  private V value;

  public Pair(K key, V value)
  {
    this.key = key;
    this.value = value;
  }
  public K getKey() {
    return this.key; } 
  public V getValue() { return this.value; } 
  public void setKey(K key) {
    this.key = key; } 
  public void setValue(V value) { this.value = value;
  }
}

Some generic type information is retained in the .class file - enough to allow you to determine, via reflection, that the type Pair is generic, and for classes that have Pair members, what the types of the generic parameters are and so on. .class文件中保留了一些泛型类型信息-足以让您通过反射来确定类型Pair是泛型的,对于具有Pair成员的类,泛型参数的类型等等。 The fact that this information is retained forms the basis of techniques like super type tokens that allow you pass around type tokens which retain information about their generic parameters. 保留此信息的事实构成了诸如超级类型令牌之类的技术的基础,该技术使您可以传递保留有关其通用参数信息的类型令牌。

Outside of reflection, however, type erasure means that the Pair class is mostly going to behave as in the stripped version in the "Answer" from the Oracle website. 但是,在反思之外,类型擦除意味着Pair类的行为将与Oracle网站“ Answer”中剥离版本的行为类似。 In particular, the actual bytecode for the methods won't have reference to generic types K or V - only Object, and the method signatures will accept and return Object . 特别是,方法的实际字节码将不会引用通用类型K或仅V Object,并且方法签名将接受并返回Object

In this case, JD-GUI is just being smart and using the information stored in the .class file to restore the generic information in the decompiled output, but rest assure the types are erased in the bytecode. 在这种情况下,JD-GUI只是很聪明,并且使用存储在.class文件中的信息来还原反编译输出中的通用信息,但是请确保将字节码中的类型删除。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM