3

有人可以向我解释为什么以下代码不起作用吗?

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 接口。为什么在这个例子中接口的位置如此重要?

4

1 回答 1

2

原因是擦除T是边界中最左边的类型。从getClass()文档中:

实际结果类型是Class<? extends |X|>在哪里擦除调用|X|的表达式的静态类型。getClass

JLS 规定“类型变量的擦除是其最左边界的擦除”(参见此处)。所以类型obj.getClass()Class<? extends Textable>在第一种情况下,Class<? extends Entity>在另一种情况下。

于 2012-07-11T01:00:43.757 回答