[英]Java nested self referential generic
我有一个类,它有一个自引用泛型参数和一个具有相同超类的参数。 静态函数与类具有相同的边界。
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) {
}
}
这会产生以下错误。
绑定不匹配:Bar <T,C>类型的泛型方法foo(S_T)不适用于参数(C)。 推断的类型C不是有界参数<S_T extends Bar <S_T,S_C >>的有效替代
我无法弄清楚为什么C
不能传入foo()
因为C
是Bar<C,?>
而且通配符是一个Bar
因为声明中的第二个参数表示它扩展了Bar。
我知道这可能是一个坏主意,并产生难以理解的代码,但我真的想知道为什么这不编译。
简短的回答是Java类型推断实际上非常蹩脚。
Java没有对通配符执行任何智能推理?
在Bar
的声明中推断它在逻辑上受Bar< ?, ? >
Bar< ?, ? >
(也不是那个界限中的?
本身是有界的,等等)。 一旦你把?
这本身就是Java所知道的。 虽然没有什么可以阻止你在Bar
的声明中将这个限制放在通配符上,但即使这对Java没有帮助; Java会不会假设两个独立的?
s指的是同一类型,即使更深入的分析意味着必须这样做。 换句话说,即使使用以下代码,编译错误仍然存在:
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()的类型是
<S_T extends Bar<S_T,S_C> > void foo(S_T)
然后在两个不同的上下文中调用它,这些上下文需要foo()
的不同静态类型。
在第一个上下文中, S_T
具有类型T
而在第二个上下文中,它具有类型C
但是T
和C
被声明为Bar<T,?>
和Bar<C,?>
,它们是静态不兼容的类型。 我猜想编译器在第一次调用中计算出foo()
的类型,然后正确地假设,类型必须始终保持相同,而不是。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.