在java中实例化自绑定泛型

时间:2014-11-24 07:42:56

标签: java generics

可能是一个简单的问题,但我似乎无法出于某种原因这样做。如何从下面的类中实例化BinaryTree类型的对象:

public class BinaryTree<N extends BinaryTree.BTNode<N>> {

public static class BTNode<N extends BTNode<N>> {
    public N left;
    public N right;
    public N parent;    
}
//some methods which return variables of type N
//or take variables of type N as arguments
}

这两种:

BinaryTree<BTNode> tree = new BinaryTree<BTNode>();

BinaryTree<BTNode<BTNode>> tree = new BinaryTree<BTNode<BTNode>>();

在Eclipse中生成一个编译器错误,说BTNode类型不是有界参数的有效替代N扩展BTNode。

这个结构的原因是我希望能够扩展BinaryTree和BTNode并让子类调用超类函数返回类型N的变量,并且N是BTNode的子类的类型,而不是类型BTNode。

我觉得我可能会遗漏一些显而易见的东西,但我已经广泛搜索并花了相当多的时间尝试不同的事情,我仍然无法做到这一点。

感谢任何帮助。

2 个答案:

答案 0 :(得分:2)

不完全是您问题的答案,但我认为您的问题是由次优设计引起的。保持你的类型简单!对于二叉树,我希望type参数是树中 data 的类型,即节点标签的类型。由于您也可以使用类型变量作为类型参数,因此这应该是您想要的。

public class BinaryTree<E> {

    public static class BTNode<T> {
        public T label;
        public BTNode<T> left;
        public BTNode<T> right;
        public BTNode<T> parent; 
    }
    //some methods which return variables of type BTNode<E>. 
    //or take variables of type BTNode<E> as arguments
}

答案 1 :(得分:0)

我最终想出了如何完成我想做的事情,我认为我会为了后人的缘故而发帖。

基本上,我有

Class Node<N extends Node<N, E>, E> {
    N left, right, parent;
    E element;

Class Tree<N extends Node<N, E>, E> {
    N rootNode;
    N externalNode;
    public N findNode(E e)   //returns the node with element e
    public boolean add(E e)  //adds a new node of type N with 
                             //  element e to the tree
    //etc

这样构造它的目的是,如果稍后扩展,子类可以调用超类方法,包括构造函数,并且可以创建或返回正确的N类型。我有一个可以扩展的通用节点,以及一个可以扩展的通用树,当使用其中任何一个的后代时,我可以调用超类add(E e)方法并确保创建和添加包含e的正确类型等等......

例如:

Class XNode<N extends XNode<N, E>, E> extends Node<N, E> {

Class XTree<N extends XNode<N, E>, E> extends Tree<N, E> {

无论如何,我遇到的问题是我无法实例化Node<N extends Node<N, E> E>类型的对象,因为无论我作为参数传递的是什么,我都会收到错误<parameter> is not a valid substitute for the bounded parameter N extends Node<N, E>, E

解决方案是创建一个类:

Class SampleNode<E> extends Node<SampleNode<E>, E>

我添加了一个N个样本;到Tree类,并更改了Tree的构造函数,以便可以传递示例节点类型的实例。现在我可以实例化:

SampleNode<ElementType> sample = new SampleNode<ElementType>();
Tree<SampleNode<ElementType>, ElementType> tree 
    = new Tree<SampleNode<ElementType>, ElementType>(sample);

使用以下命令在树中创建新节点:

public N newNode() {
   return (N)(sample.getClass().newInstance())  //needs try-catch and
                                                //  suppress unchecked

无论如何,我不确定是否有人关心,但我认为无论如何我都会发布解决方案。