我有以下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对象的值。那不是通过参考传递吗?
答案 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中,一切 按值传递。因此,第二种方法中的root
是bstRoot
的副本,修改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是实例变量。