未能将User对象用作参数?在Java泛型中扩展用户

时间:2015-02-22 12:35:00

标签: 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();
}

导致编译错误:

  

SymmetricIndexedRealMatrix类型中的getElement方法(捕获#10-of?extends User,capture#10-of?extends User)不适用于参数(User,User)

出了什么问题以及如何解决?

2 个答案:

答案 0 :(得分:1)

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

记住acroynm PECS - 生产者扩展,消费者超级。您正在将User传递给Matrix上的方法,以便矩阵消耗您的值。其类型需要与Matrix<? super User>兼容,因此crf也需要CRF<? super User>CRF<User>CRF<? super User>的子类型。

答案 1 :(得分:1)

假设您有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个用户,而不是{{1 }}

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

crf

将解决错误。