Java nested self referential generic
我有一个类,它有一个自引用的泛型参数和一个属于同一个超类的参数。静态函数与类具有相同的边界。
1 2 3 4 5 6 7 8 9 10 | public class Bar<T extends Bar<T, C>, C extends Bar<C, ?>> { Bar() { foo((T) null); foo((C) null);//compile error } static <S_T extends Bar<S_T, S_C>, S_C extends Bar<S_C, ?>> void foo(S_T t) { } } |
这会产生以下错误。
Bound mismatch: The generic method foo(S_T) of type Bar
is not
applicable for the arguments (C). The inferred type C is not a valid
substitute for the bounded parameter>
号
我不明白为什么
我知道这可能是一个坏主意,并产生了难以理解的代码,但我真的想知道为什么这不能编译。
简短的答案是Java类型的推理实际上是相当蹩脚的。
在EDCOX1(10)的声明中,Java没有对通配符EDOCX1 9进行任何智能推理,以推断它在逻辑上是由EDCOX1〔11〕限制的(也不意味着EDCOX1在该约束中的9个S本身是有界的,等等)。一旦你把EDOCX1,9本身,这就是所有的Java知道。尽管没有任何东西阻止您在EDCOX1(10)中声明通配符,即使这样对Java也没有帮助;Java不会假设两个单独的EDCOX1×9个s指的是同一类型,即使更深的分析暗示它们必须是相同类型的。换句话说,即使使用以下代码,编译错误仍然存在:
1 2 3 4 5 6 7 8 9 10 | public class Bar<T extends Bar<T, C>, C extends Bar<C, ? extends Bar<?, ? extends Bar<?, ?>>>> { Bar() { foo((T) null); foo((C) null);//compile error } static <S_T extends Bar<S_T, S_C>, S_C extends Bar<S_C, ? extends Bar<?, ? extends Bar<?, ?>>>> void foo(S_T t) { } } |
号
对于泛型,我不是一个裂缝,但我认为问题在于您将foo()的类型声明为
1 | <S_T extends Bar<S_T,S_C> > void foo(S_T) |
然后在两个不同的上下文中调用它,这些上下文要求
在第一个上下文中,