Java 未按预期工作的泛型对象集合
我有自己的泛型类,如下所示:Java 未按预期工作的泛型对象集合,java,Java,我有自己的泛型类,如下所示: C1<T> { T value; ... void setValue(T val) { this.avlue = val; } } C1<Integer> a; C1<Float> b; C1<String> c; ... C1<Type1> 接下来我要做的是: 迭代列表以执行以下操作: list.get(i).setValue(obj); 其中obj
C1<T> {
T value;
...
void setValue(T val) {
this.avlue = val;
}
}
C1<Integer> a;
C1<Float> b;
C1<String> c;
...
C1<Type1>
接下来我要做的是:
迭代列表以执行以下操作:
list.get(i).setValue(obj);
其中obj是Object类型的变量,可以是整数、浮点等
现在的问题是,从列表返回的C1实例(我们称之为C1)的定义如下:
C1<T> {
T value;
...
void setValue(T val) {
this.avlue = val;
}
}
C1<Integer> a;
C1<Float> b;
C1<String> c;
...
C1<Type1>
其中val2的类型为Type2,Type2不等于Type1,甚至不在同一类层次结构中(对象ofc除外)
编辑:
忘了问这个问题:)
当以上述方式访问setValue时,如何使其“类型安全”?您将集合定义为
列表
,因此它将接受任何类型为C1的对象,而不管您如何参数化该类型。如果要将其限制为仅保存特定类型的C1,则需要执行List如果将类型为C1
和C1
的对象存储在列表中,则从列表中检索元素时无法确定确切的类型。您只知道它是一个C1
(与列表中的所有元素一样)
如果您确实需要在运行时询问C1
其类型参数是什么,则需要在C1中存储一些类型令牌:
C1<T> {
private final Class<T> cls;
C1(Class<T> pCls) {
cls = pCls;
}
Class<?> getTypeParameter() {
return cls;
}
}
C1{
私人期末班;
C1(pCls类){
cls=pCls;
}
类getTypeParameter(){
返回cls;
}
}
然后可以对从列表中获得的实例调用getTypeParameter()
,并将其与预期的类型进行比较
请注意,如果使用未选中的强制转换,这仍然允许您在C1
中存储Type2
的值。如果要消除这种可能性,请在setValue()
中对照cls
检查val
的运行时类型,如果它们不匹配,则抛出异常。是的,我猜这就是问题所在,但我希望我的集合允许所有C1,无论类型1是什么(即类型1是Object)。我希望将此类型解析为在访问集合成员时的实际类型。我也许可以通过反射来实现这一点,但这是最后的手段……你们不能两全其美。如果希望集合包含任何类型的C1,则不能让编译器在编译时确保类型安全。不过,您可以在运行时使用反射进行检查,这是对的。