在泛型方法中使用自引用类型时出现绑定不匹配错误,但在泛型类声明中却没有。这是错误代码的示例:
public class Container {
public static class User<X> {} // line 1
public static class Box<U extends User<Box<U>>> {} // line 2
public static class NiceBox<U extends User<Box<U>>> {} // line 3: OK
<U extends User<Box<U>>> void niceMethod(U user) {} // line 4: NOT OK
}
在第4行上编译错误消息:绑定不匹配:类型
U
不是 有效替代类型< U extends Container.User<Container.Box<U>>>
的有界参数Container.Box<U>
我不明白为什么,谢谢您的帮助, SC
PS:请注意,与先前提出的问题不同,此处提出的问题仅存在于泛型方法中,编译器在泛型类声明中使用时接受有问题的类型绑定。
我正在使用Java 11的编译器以及最新的Eclipse发行版。
以下是有关我要实现的目标的更多详细信息。 我正在构建一个Box,它需要在类型C的上下文中在类型T的目标上执行一些工作,其中该上下文C必须满足最小接口。 然后,我需要定义处理Box的方法(因此需要绑定自引用类型的通用方法)。 这是代码:
static class Box<T,C extends MinimalContext<Box<T,C>>> {
void doSomething(T target, C context) {
// do something
}
}
interface MinimalContext<B> {
boolean validate(B box);
void print(B box);
}
// FAILS:
<T,C extends MinimalContext<Box<T,C>>>
void processBox(Box<T,C> box) {}
// Instead use:
class BoxProcessor<T,C extends MinimalContext<Box<T,C>>>
{
BoxProcessor(Box<T,C> box) {
// use box as niceMethod would do
}
}
请注意,由于该限制仅对通用方法存在,而对类不存在,因此我正在使用内部类来完成通用方法的工作……还有其他解决方案吗?
日食开发人员可以对这个限制说更多吗?
答案 0 :(得分:1)
这似乎是Eclipse编译器的限制或更高级别的严格性。 javac
可以接受该代码。
在Eclipse中,您可以编写:
public static class User<T> {}
public static class Box<T extends User<Box<T>>> {}
<T extends User<Box<?>>> void niceMethod(T user) {}
然后您可以声明一个类:
static class UserBox extends User<Box<?>> {}
Eclipse将允许您:
public static void main(String[] args)
{
Container c = new Container();
c.niceMethod(new UserBox());
}
但是这样一来,您就无法创建具体的Box
。例如:
Box<UserBox> b = new Box<>();
Eclipse不允许,但javac
允许。
我怀疑Eclipse可能做正确的事,因为您在说:
“ {Box
的类的类型参数将User
扩展为Box的类型参数,而Box的类型参数是我们正在扩展的类型。”这对我来说听起来是不可能的,但可能是我缺少了一些东西。
编辑(因为问题已更新为显示界面)
您可以定义更严格的接口,而不是将接口定义为完全通用并尝试在Box
的定义中限制上下文类型,例如:
interface BoxContext<B extends Box<?, ?>> {
boolean validate(B box);
void print(B box);
}
然后可以从Box
的定义中删除自引用泛型:
static class Box<T, C extends BoxContext<?>> {
void doSomething(T target, C context) {
// do something
}
}
然后允许您定义方法:
<T, C extends BoxContext<?>> void processBox(Box<T, C> box) {}