Java 互补泛型类

Java 互补泛型类,java,generics,generic-programming,Java,Generics,Generic Programming,我有两个抽象类: 容器、节点 一种容器将始终包含同一种节点,一种节点将只属于其对应的容器: NodeTypeA存储在ContainerTypeA中,其中不存储节点的其他子类。 NodeTypeB存储在ContainerTypeB中,其中不存储节点的其他子类。从节点到其容器的反向引用也应该知道容器的类型,因此关系是双向的 我在用Java实现这一点时遇到了问题 我是这样做的: Container<C extends Container<C,N>, N extends Node<

我有两个抽象类: 容器、节点

一种容器将始终包含同一种节点,一种节点将只属于其对应的容器: NodeTypeA存储在ContainerTypeA中,其中不存储节点的其他子类。 NodeTypeB存储在ContainerTypeB中,其中不存储节点的其他子类。从节点到其容器的反向引用也应该知道容器的类型,因此关系是双向的

我在用Java实现这一点时遇到了问题

我是这样做的:

Container<C extends Container<C,N>, N extends Node<C,N>>
Node<C extends Container<C,N>, N extends Node<C,N>>
应该等于

Node<C,N>
节点
测试用例:

其目的是:

有许多不同类型的节点和许多不同类型的交互方式。然而,它们有一些共同的主题。容器和节点应该是抽象类,我可以在其中定义方法和抽象方法来定义这些公共主题。ContainerA和NodeA将一起定义一种特定的交互方法。我使用泛型来实现这一点,因为如果我的IDE足够聪明,知道ContainerA中的任何节点始终是NodeA,并且NodeA的所有者始终是ContainerA,那么编程就会变得容易得多,因此我可以避免一些不必要的类型转换


(注意:这个问题类似但不等于)

除了几个小错误(
抽象
在java中应该在
之前,在第16行的
节点
的构造函数中错误的类型变量
L
,尝试访问第18行的私有字段),您的语义问题在第18行。
的类型是
节点
,而不是
N

实现目标的一种方法是向
节点添加一个抽象方法,该节点返回
N
,所有子类都将通过返回
this
来实现它

abstract protected N me();
然后,将适当的setter添加到
容器中后,将第18行更改为

owner.add( me() );

除了几个小错误(
abstract
在java中应该在
class
之前,第16行
节点的构造函数中的类型变量
L
错误,尝试访问第18行的私有字段),您的语义问题在第18行。
的类型是
节点
,而不是
N

实现目标的一种方法是向
节点添加一个抽象方法,该节点返回
N
,所有子类都将通过返回
this
来实现它

abstract protected N me();
然后,将适当的setter添加到
容器中后,将第18行更改为

owner.add( me() );
我怎样才能让程序理解这一点
N
应等于
节点

他们不平等<代码>N
扩展
节点

但是这种类型擦除规则的弯曲是不必要的,即使它在程序的上下文中是安全的

我怎样才能让程序理解这一点
N
应等于
节点

他们不平等<代码>N
扩展
节点


但是这种类型擦除规则的弯曲是不必要的,即使它在程序的上下文中是安全的。

确切的错误消息是什么?是否可以包含导致此错误的最小但完整的类?此处似乎很好:。请构造一个最小的测试用例:关键字“abstract”应该在关键字“class”之前。我匆忙地写了那封信。奇怪的是,网站的编译器并没有首先抱怨这个问题,而只是抱怨泛型。确切的错误消息是什么?是否可以包含导致此错误的最小但完整的类?此处似乎很好:。请构造一个最小的测试用例:关键字“abstract”应该在关键字“class”之前。我匆忙地写了那封信。奇怪的是,该网站的编译器并没有首先抱怨这一点,而只是抱怨泛型。
private List<N> nodes;
List<N> nodes = ...;

Node<C, N> node = new Node<>(...);
nodes.add(node);  // ERROR because node might not be the right subclass
List<Node<C, N>> nodes = ...;

Node<C, N> node = new Node<>(...);
nodes.add(node);  // OK.
List<N> nodes = ...;
N node = new Node<C, N>(...);   // ERROR.  Not all Node<C, N> are N
// N is a sub-type not a super-type of Node<C, N>
nodes.add(node);
N node = (N) new Node<C, N>(..);  // Unchecked conversion