有人可以向我解释为什么以下代码不起作用吗?
public class TestGeneric {
EntityManager entityManager = new EntityManager();
public <T extends Textable & Entity> void doAction(T obj) {
entityManager.getAliasForEntityClass(obj.getClass());
}
}
class EntityManager {
public String getAliasForEntityClass(Class<? extends Entity> clazz) {
return clazz.getCanonicalName();
}
}
interface Entity {
Long getId();
}
interface Textable {
String getText();
}
我收到以下错误:
The method getAliasForEntityClass(Class<? extends Entity>) in the type EntityManager is not applicable for the arguments
(Class<capture#1-of ? extends Textable>)
如果我这样写,我没有任何错误:
public class TestGeneric {
EntityManager entityManager = new EntityManager();
public <T extends Entity & Textable> void doAction(T obj) {
entityManager.getAliasForEntityClass(obj.getClass());
}
}
class EntityManager {
public String getAliasForEntityClass(Class<? extends Entity> clazz) {
return clazz.getCanonicalName();
}
}
interface Entity {
Long getId();
}
interface Textable {
String getText();
}
模板<T extends Entity & Textable>
和<T extends Textable & Entity>
表示:T必须实现Entity和Textable接口。为什么界面的位置在这个例子中如此重要?
答案 0 :(得分:2)
原因是T
的删除是绑定中最左边的类型。来自getClass()
文档:
实际结果类型为
Class<? extends |X|>
,其中|X|
为 擦除getClass
所在表达式的静态类型 调用。
JLS指定“类型变量的擦除是其最左边界的擦除”(参见here)。因此obj.getClass()
的类型在第一种情况下为Class<? extends Textable>
,在另一种情况下为Class<? extends Entity>
。