Java将泛型类型对象作为方法参数传递

时间:2016-05-01 06:46:22

标签: java generics

我有以下java类,它具有实例变量属性作为声明类时传递的泛型类型。

当我尝试将属性传递给它作为方法参数时,如果我更改参数本身的值,它似乎不会更改其值。

代码:

public class BST<T extends Comparable<T>, S>{
    private Node<T, S> bstRoot;

    public Node<T,S> getRoot() {
        return bstRoot;
    }
    public void setRoot(Node<T,S> root) {
        this.bstRoot = root;
    }   
    public boolean put(T key, S value){
        Node<T,S> node = new Node<T,S>(key, value);
        return put(node, bstRoot);
    }
    private boolean put(Node<T,S> node, Node<T,S> root){
        if(root == null){
            root = node;
        }
        else{
            if(root.compareTo(node) < 0){
                put(node, root.getRightChild());
            }
            else{
                put(node, root.getLeftChild());
            }
        }
        return true;
    }
}

当我执行以下操作时:

public class BSTTest {
    public static void main(String[] args){
        BST<Integer, String> bst = new BST<Integer, String>();
        bst.put(10, "Hello10");
    }
}

执行put之后,bstRoot仍为null,而不是设置为具有键10和值Hello10的Node对象的值。那不是通过参考传递吗?

3 个答案:

答案 0 :(得分:5)

问题如下。在您的第一个put方法中,您执行此操作:

return put(node, bstRoot);

您的第二个put方法如下所示:

private boolean put(Node<T,S> node, Node<T,S> root){
    if(root == null){
        root = node;
    }

因此,在第一个put方法中,您将bstRoot作为第二个root方法的put参数传递。

您似乎期望bstRoot通过引用传递,因此第二个put方法将设置bstRoot

事实并非如此。在Java中,一切 按值传递。因此,第二种方法中的rootbstRoot的副本,修改root的值不会修改bstRoot

答案 1 :(得分:2)

这看起来不太合适:

if(root == null){
    root = node;
}

为什么呢? root是您方法中定义的变量。 It doesn't have the same lifecycle作为您实例中的字段。

private boolean put(Node<T,S> node, Node<T,S> root)

在这里为空树实际使用bstRoot会更可靠。

if(bstRoot == null){
    bstRoot = node;
}

答案 2 :(得分:0)

 private boolean put(Node<T,S> node, Node<T,S> root){
        if(root == null){
            root = node;
        }
        else{
            if(root.compareTo(node) < 0){
                put(node, root.getRightChild());
            }
            else{
                put(node, root.getLeftChild());
            }
        }
        return true;
    }

这里root有一个本地范围。您必须将此根目录设置为bstRoot。因为bstRoot是实例变量。