我在树中有一个节点,它可能有一个父节点(也是一个节点)和一些子节点(也是节点)。
我想用Java的泛型做的是允许传入子节点将存储在其中的List类型以及节点将保存的数据。因此,我编写了下面的类,编译器似乎对它很满意。
public class Node<T extends List<Node<T, U>>, U>
{
public Node<T, U> parent;
public T children;
public U data;
private Class<T> tClass;
public Node(Class<T> tClass) throws InstantiationException, IllegalAccessException
{
this.tClass = tClass;
this.children = this.tClass.newInstance();
}
}
问题是当我试图初始化一个节点。
Node<ArrayList, NodeData> node = new Node(ArrayList.class);
编译器报错,因为ArrayList上的Bound不匹配。我试图修复它与以下尝试:
Node<ArrayList<Node>, NodeData> node = new Node(ArrayList.class);
Node<ArrayList<Node<ArrayList, NodeData>>, NodeData> node = new Node(ArrayList.class);
Node<ArrayList<Node<ArrayList<Node>, NodeData>>, NodeData> node = new Node(ArrayList.class);
Node<ArrayList<Node<ArrayList<Node<ArrayList, NodeData>, NodeData>>, NodeData> node = new Node(ArrayList.class);
就像你看到的,这个会一直持续下去,我知道我可以用
来解决这个问题public class Node<T extends List<Node>, U>
{
public Node<T, U> parent;
public T children;
public U data;
private Class<T> tClass;
public Node(Class<T> tClass) throws InstantiationException, IllegalAccessException
{
this.tClass = tClass;
this.children = this.tClass.newInstance();
}
}
允许我使用:
Node<ArrayList<Node>, NodeData> node = new Node(ArrayList.class);
但是当我这样做的时候:
node.children.get(0).children;
返回类型是List,而不是我想要的ArrayList。
我想做的是可能的吗?如果是这样,也许有人可以告诉我哪里错了,或者如果没有,最好的选择是什么?
谢谢,瑞奇。
正如您所发现的,递归泛型很快就会变得非常复杂。我有两个选择。
1:删除T并让子节点声明为List<Node<U>>
2:声明节点为抽象节点,添加一个self引用,并定义一个具体的ArrayList节点引用。
abstract class Node<N extends Node<N, T, U>, T extends List<N>, U>
{
public Node<N, T, U> parent;
public T children;
public U data;
private Class<T> tClass;
public Node(Class<T> tClass) throws InstantiationException, IllegalAccessException
{
this.tClass = tClass;
this.children = this.tClass.newInstance();
}
{
Node<ALNode<Integer>, ArrayList<ALNode<Integer>>, Integer> node = new ALNode<Integer>();
ALNode<Integer> node2 = new ALNode<Integer>();
}
}
class ALNode<U> extends Node<ALNode<U>, ArrayList<ALNode<U>>, U> {
public ALNode() throws InstantiationException,
IllegalAccessException {
super((Class) ArrayList.class);
}
}