我有一个依赖于泛型来在内部绑定类型的类。
class C<T1, T2 extends T1> {
T1 e1;
T2 e2;
/* stuff */
}
在我的代码中,我知道虽然c.e1
和c.e2
可能没有相同的类,但c.e2
是c.e1
类的子类的实例。
我需要创建这些List
的{{1}},并且这些元素不会共享公共基类。不过,我想保留这样一个事实:c
的每个元素都具有相互之间的属性。
理想情况下,我想创建一个List
&#34;但是&#34;我不知道用于指定此行为的任何语法。
使用List<C<?, ? extends ...>>
在我看来,我丢失了泛型类型。
这个集合的正确方法是什么?
答案 0 :(得分:2)
由于T2
在C
的声明中有界限,即使您使用通配符,也始终会保留它是T1
的子类型的事实。即 C
的特征是第二个类型参数扩展第一个。
所以你可以使用List<C<?, ?>>
。
当您尝试将泛型参数绑定到类型变量时,您已经可以看到这种方法。 e.g:
public static <T1, T2> void m(List<C<T1, T2>> list) { ... }
^^-- Bound mismatch
您需要使用:
public static <T1, T2 extends T1> void m(List<C<T1, T2>> list) {...}
或者:
public static <T1> void m(List<C<T1, ? extends T1>> list) {...}
让编译器感到高兴。
答案 1 :(得分:0)
我找到了一种在自定义(非泛型)类型中编码类型约束的解决方案。
所以现在我有这些课程:
class MainLogic {
List<TypeHelper<?,?>> elements = new ArrayList<>();
<T1, T2 extends T1> void addElement(T1 e1, T2 e2) {
this.elements.add(new TypeHelper<T1,T2>(e1, e2));
}
void logic() {
for (TypeHelper<?, ?> element: elements)
element.logicHelper(this);
}
<T1, T2 extends T1> void logicHelper(T1 e1, T2 e2) {
// here finally I have the variables constrained
}
}
class TypeHelper<T1, T2 extends T1> {
T1 e1;
T2 e2;
void logicHelper(MainLogic ml) {
ml.logicHelper(e1, e1);
}
}