无法使用用户对象作为参数?在 Java 泛型中扩展用户

Failing to use User object as parameter for ? extends User in Java generics

我在使用泛型时遇到问题。首先我宣布

public class SymmetricIndexedRealMatrix<T> implements iIndexedMatrix<T,T, Double>{
    public Double getElement(T rowObject, T columnObject) { ... }
}

然后

public class CRF<U> {
    private SymmetricIndexedRealMatrix<U> binaryEnergy;
    private Set<U> labelSet;
    public SymmetricIndexedRealMatrix<U> getBinaryEnergy() {
        return binaryEnergy;
    }
    public Set<U> getLabelSet() {
        return labelSet;
}
    ...
}

那我就用这部分代码

CRF<? extends User> crf = new CRF<User>(sourceGraph, targetGraph.getElements(User.class), getUnaryEnergyComputer(), getBinaryEnergyComputer()
...
for (User targetUser1 : crf.getLabelSet()) {
    for (User targetUser2 : crf.getLabelSet()) {
        System.out.print(crf.getBinaryEnergy().getElement(targetUser1, targetUser2) + " ");
    }
    System.out.println();
}

并导致编译错误:

The method getElement(capture#10-of ? extends User, capture#10-of ? extends User) in the type SymmetricIndexedRealMatrix is not applicable for the arguments (User, User)

出了什么问题,应该如何解决?

只需将 crf 声明为 CRF<User> 类型;或者,如果您确实需要通配符类型,CRF<? super User>.

记住首字母缩写词 PECS - 生产者扩展,消费者超级。您将 User 传递给 Matrix 上的方法,因此该矩阵 消耗 您的值。它的类型需要与 Matrix<? super User> 兼容,因此 crf 也需要是 CRF<? super User>CRF<User>CRF<? super User> 的子类型。

假设您有 2 个子 类 扩展 User - SubUser1SubUser2.

以下代码是可能的:

CRF<? extends User> crf = new CRF<SubUser1>(...);
User targetUser1 = new SubUser2();
User targetUser2 = new SubUser2();

现在,如果您像之前那样尝试调用 crf.getBinaryEnergy().getElement(targetUser1, targetUser2),它将无法正常工作,因为分配给 crf 的特定实例需要 SubUser1 个用户,而不是 [=14] =].

即使在您的实际代码中您只使用了 User 类型(没有子 类),编译器也无法知道将分配给的实例的确切类型crf 在运行时,这就是您的代码无法编译的原因。

CRF<User> crf = new CRF<User> (...);

将解决错误。