无法使用用户对象作为参数?在 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
- SubUser1
和 SubUser2
.
以下代码是可能的:
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> (...);
将解决错误。
我在使用泛型时遇到问题。首先我宣布
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
- SubUser1
和 SubUser2
.
以下代码是可能的:
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> (...);
将解决错误。