所以,我有一些代码看起来大约像(为了简洁而被截断 - 忽略诸如公共(public)成员变量之类的东西):
public class GenericThingy<T> {
private T mValue;
public final T[] mCandidates;
public GenericThingy(T[] pCandidates, T pInitValue) {
mCandidates = pCandidates;
mValue = pInitValue;
}
public void setValue(T pNewValue) {
mValue = pNewValue;
}
}
public class GenericThingyWidget {
private final GenericThingy<?> mThingy;
private final JComboBox mBox;
public GenericThingyWidget (GenericThingy<?> pThingy) {
mThingy = pThingy;
mBox = new JComboBox(pThingy.mCandidates);
//do stuff here that makes the box show up
}
//this gets called by an external event
public void applySelectedValue () {
mThingy.setValue(mBox.getSelectedItem());
}
}
}
我的问题是 mThingy.setValue(mBox.getSelectedItem());调用会生成以下错误:
方法setValue(capture#4-of ?)
类型 Generics.GenericThingy<capture#4-of ?>
不适用于参数(对象)
我可以通过删除 <?>
来解决这个问题来自 GenericThingyWidget 中 mThingy 和 pThingy 的声明 - 这给了我一个“GenericThingy 是原始类型。对 GenericThingy 的引用应该参数化”警告。
我还尝试将 setValue 调用替换为
mThingy.setValue(mThingy.mCandidates[mBox.getSelectedIndex()]);
我真的希望它能够工作,但这产生了一个非常相似的错误:
方法setValue(capture#4-of ?)
类型 Generics.GenericThingy<capture#4-of ?>
不适用于参数 (capture#5-of ?)
有什么方法可以做到这一点而不生成“原始类型”警告(我可以接受的“未经检查的转换”警告)并且不将 GenericThingyWidget 变成通用类型?我想我可以将 mBox.getSelectedItem() 的返回值转换为某个东西,但我不知道那会是什么。
作为一个额外的问题,为什么对 mThingy.setValue 的替换调用不起作用?
最佳答案
您在 GenericThingyWidget
中缺少信息。
您放置的 ?
表示:任何扩展对象的类。这意味着任何,而不是某个特定的,但我不知道是哪一个。 Java 无法将一个 ?
与另一个相关联,它们无法在类层次结构树中将一个与另一个相关联。所以
mThingy.setValue(mThingy.mCandidates[mBox.getSelectedIndex()]);
这尝试将任何类的对象放入setValue中,该对象正在等待任何其他类,但?
不能告诉 Java 这两个 any 应该是同一个类。
如果没有参数化GenericThingyWidget
,我看不到任何方法来解决它。
我会做什么:参数化GenericThingyWidget
,并创建一个工厂静态参数化方法:
public static <T> GenericThingyWidget<T> make(T someObject){
...
}
关于Java 泛型 : casting to ? (或使用任意 Foo<?> 的方法),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1375718/