我如何在Java泛型中表达以下类型关系:
class MyClass<T> { }
interface MyInterface<T extends MyClass> {
void m1(T<Integer> argument);
void m2(T<String> argument);
void m3(T<?> argument);
}
没有编译器投诉。这甚至可能吗?我想确保所有方法都接收MyClass
的相同(子)类,同时不破坏类型安全性。在域中,不同的子类og MyClass
不会出现。我真的必须列出三个泛型类型变量,如下所示:
class MyClass<T> { }
interface MyInterface<T1 extends MyClass<Integer>,
T2 extends MyClass<String>, T3 extends MyClass<?>> {
void m1(T1 argument);
void m2(T2 argument);
void m3(T3 argument);
}
我觉得读起来很糟糕,并没有像我希望的那样表达我的意图。这个问题与我关于泛型Raw types inside of generic definition的其他问题有关,这仍然让我感到困惑。也许有人可以帮忙!谢谢。
答案 0 :(得分:0)
不确定它是否是一个好方法。我觉得使用下面的方法你不能“绑定”参数m1
,m2
,m3
方法,而是在调用你时可以有权使用任何类型的参数{{1} }或MyClass<Integer>
MyClass<String>
和实施者
public class MyClass<T> { }
interface MyOtherClass<T extends MyClass<?>> {
void m1(T argument);
void m2(T argument);
void m3(T argument);
}
这就是你可以打电话的方式
class MyOtherClassImpl<T extends MyClass<?>> implements MyOtherClass<T> {
@Override
public void m1(T argument) {
}
@Override
public void m2(T argument) {
}
@Override
public void m3(T argument) {
}
}
答案 1 :(得分:0)
嗯,我意识到我得到了因为我无法在Java中表达这一点:
class MyClass<T> { }
interface MyInterface<T extends MyClass> {
T<S> m1(S argument);
}
然而,我找到了一个相当奇特的解决方案。我没有在每个子接口中手动升级我的返回类型,而是使用Spoon在编译之前读取和写入相应的源代码。编译器看到我的代码就像我手动覆盖每个接口中的返回类型一样。这使我的代码与每个Maven构建的超级界面保持同步,我不必再担心它了。
这个解决方案可能不适合所有人,但它是我能够以DNRY的精神想到的最干净的解决方案。