我在oracle网站上找到了以下问题和答案
以下类在类型擦除后转换为什么?
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;
}
答案:
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;
}
但是当我使用JD-GUI反编译类文件时,我仍然看到所有通用类型与实际源代码中的类似。
这是否意味着泛型类型保留在类文件中?我正在使用Java 6.
使用JD-GUI的类的反编译器版本如下。我正在使用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;
}
}
答案 0 :(得分:6)
.class文件中保留了一些泛型类型信息 - 足以允许您通过反射确定类型Pair是通用的,对于具有Pair成员的类,通用参数的类型是什么等等上。保留此信息的事实构成了super type tokens等技术的基础,允许您传递保留有关其通用参数的信息的类型令牌。
然而,在反射之外,类型擦除意味着Pair
类的行为与Oracle网站的“答案”中的剥离版本大致相同。特别是,方法的实际字节码不会引用泛型类型K
或V
- 仅对象,方法签名将接受并返回Object
。
在这种情况下,JD-GUI只是很聪明,并使用存储在.class文件中的信息来恢复反编译输出中的通用信息,但请确保在字节码中删除类型。