我试图理解为什么不允许在一个类中编写这两个方法
public bool plus(List<String>) {return true;}
public bool plus(List<Integer>) {return true;}
我试图弄清楚它与类型擦除有什么关系,但是当我反编译以下代码时
public class Test<T> {
boolean plus2(List<T> ss) {return false;}
boolean plus(List<String> ss) {return false;}
boolean plus(Set<Integer> ss) {return false;}
}
当我用Java反编译器(jd)
反编译时,我得到了同样的结果即使我打印字节代码,我也能清楚地看到类型 (查看声明的SO answer,但请确保在字节码中删除类型&#39;)
Compiled from "Test.java"
public class com.example.Test<T> {
public com.example.Test();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
boolean plus2(java.util.List<T>);
Code:
0: iconst_0
1: ireturn
boolean plus(java.util.List<java.lang.String>);
Code:
0: iconst_0
1: ireturn
boolean plus(java.util.Set<java.lang.Integer>);
Code:
0: iconst_0
1: ireturn
}
答案 0 :(得分:10)
您的编译器需要能够根据字节代码中的信息检查泛型类型信息。
Java 5.0+以字节代码记录通用信息,但它不会在对象实例中记录它。
e.g。无法获得此List的泛型类型
// list.getClass() is just ArrayList which doesn't record the generic type.
List list = new ArrayList<String>();
然而这确实
// list.getClass() is not ArrayList
// list is an instance of a class which extends ArrayList<String>
List list = new ArrayList<String>() { };
ParameterizedType t = (ParameterizedType) list.getClass().getGenericSuperclass();
assert t.getRawType() == ArrayList.class;
assert t.getActualTypeArguments()[0] == String.class;
这是因为ArrayList的子类的字节代码记录了它的父级中使用的泛型。
注意:这也适用于字段,构造函数/方法参数作为返回类型,实际类型记录在字节代码中。
但是,这些都不意味着实例的泛型类型可用(尽管如果以字节代码记录,父类/接口的泛型类型可用。