按值传递-树未删除[重复]

Posted

技术标签:

【中文标题】按值传递-树未删除[重复]【英文标题】:Pass by value - tree not deleted [duplicate] 【发布时间】:2013-01-06 11:50:10 【问题描述】:

可能重复:Java, pass-by-value, reference variables

我对 JAVA 究竟如何通过值传递与对象一起工作有点困惑。例如如果我将对象作为参数传递给方法。我知道它的地址是作为值传递的。好的,对象的副本是否保留在传递对象的原始位置表单中,因为如果我在被调用的 API 中创建对对象的新引用并更改其中的某些内容,它不会反映在我的调用者中API。

下面是一段典型的代码,我尝试删除一棵树,但它仍然存在。

public class DeleteTree 

public static void main(String[] args) 

    Node root = new Node(5);
    for(int i = 0 ; i < 10 ; i++)
        if(i == 5) continue;
        root.insertNode(i);
    

    deleteTreeNonRecursive(root);
    System.out.println(root.key);



public static void deleteTreeNonRecursive(Node root)

    Queue<Node> q = new LinkedList<Node>();
    q.add(root);
    while(!q.isEmpty())
        Node temp = q.poll();
        if(temp.leftChild != null)q.add(temp.leftChild);
        if(temp.rightChild != null)q.add(temp.rightChild);
        temp = null;
    


预期的 O/P: 空指针异常。

实际 O/P: 5.

【问题讨论】:

你期待一个空指针异常在哪里?为什么?您不会更改新参考“temp”中的任何内容。您的问题与您的代码不符。 【参考方案1】:

在 Java 中,您总是通过值传递对对象的引用(该对象本身已分配到堆上)。不会发生重复,因为您只是在传递指针。

在您的示例中,您只是设置 temp = null 但这确实没有任何作用,因为 temp 是指向 Node 的指针,但它是函数的本地变量,当您将其设置为 null 时,原始对象是根本没有触及,因为您只是在修改引用的值而没有修改被引用的对象。

要删除树,您只需要这样做:

Node root = new Node(5);
    for(int i = 0 ; i < 10 ; i++)
        if(i == 5) continue;
        root.insertNode(i);
    

root = null;

【讨论】:

感谢您的解释。所以,你的意思是说,如果我想删除一棵树..我可以只是 root object = null 并且它将被 JVM GC 自动删除,因为其余节点将没有引用。 @ASingh:在没有引用后,GC 可能会也可能不会释放它。您不应该关心对象何时或是否被释放。【参考方案2】:

Java 始终使用按值传递。当涉及到对象引用时,它是传递的引用值。当您传递对象引用时,它是传递的引用值的副本。使用它,您始终可以访问该对象并更改其属性(只要适用),但将该引用分配给另一个对象或 null 显然不会对调用方法中的原始引用产生任何影响。

【讨论】:

以上是关于按值传递-树未删除[重复]的主要内容,如果未能解决你的问题,请参考以下文章

java:按值传递或按引用传递[重复]

Java既是按值传递又是按引用传递[重复]

在C ++中的继承上下文中按值传递对象[重复]

R按值传递或按引用传递[重复]

Common Lisp:按值传递与按引用传递[重复]

在 C# 中,我应该按值传递参数并返回相同的变量,还是按引用传递?