Before I show my problem what I understand is: Java uses pass by value.

Said that, In below example, I pass "my_root" reference , to NodeModify(),

and in line "NodeModify(my_root);" expect compiler to pass copy of memory address of "my_root " and inside function make "root = new_node;" i.e => expect root's memory location/address be updated to / point to location where "new_node" is.

Surprisingly, it doesn't reflect back in main() function from where it was called, why is this so?

package com.trees;

public class NodeExample {
    public static void NodeModify(Node root){
        System.out.println("[NodeModify] fresh root is : " + root);
        Node new_node = new Node(0);
        System.out.println("[NodeModify] new node is : " + new_node);
        root = new_node;
        System.out.println("[NodeModify] root is : " + root);
    }
    public static void main(String[]arg){
        Node my_root = new Node(55);
        System.out.println("my root before NodeModify is: " + my_root);
        NodeModify(my_root);
        System.out.println("my root after NodeModify is: " + my_root);
    }
}

However, if I do the same with other reference, like ArrayList, it gets updated in main() as I expect! Example:

package com.trees;

import java.util.ArrayList;

public class ArrayListUpdateClass {

    public static void updateMyArrayList(ArrayList<String> sample){
        sample.add("was updated!");
    }
    public static void main(String[]args){
        ArrayList<String> my_list = new ArrayList<String>();
        my_list.add("My list ");
        System.out.println("**Before call list is:**");
        printArrayList(my_list);
        updateMyArrayList(my_list);
        System.out.println("\n**After call list is:**");
        printArrayList(my_list);
    }
    private static void printArrayList(ArrayList<String> my_list) {
        for(String item:my_list){
            System.out.println(item);
        }

    }
}

What am I missing here, I had hard time updating root node in making Binary tree.

有帮助吗?

解决方案

Passing in a reference to a method means the reference is a value. This value is made available to you by the name of the method parameter root, which lives on the stack. Assigning different references to the parameter root will be reflected only inside the method, but as soon as you leave the method, everything on the stack is lost.

What you like to achieve is a modification of the value hold by the variable my_root. To do that, you need to pass in a reference to the variable my_root and not only the value hold by my_root. This can be done, for example, by passing in a container which holds references to Nodes. A Java Collection is one of those containers. Passing in the container and modifying its values will be reflected outside the method NodeModify(Node root).

Some side notes:

  • in Java a method should start with a lower-case letter or an underscore
  • use camel-case for variable names instead of underscores to separate words, except when you define constants

其他提示

Your confusion comes from the fact, that you misinterpreted call-by-value.

[...] inside function make "root = new_node;" i.e => expect root's memory location/address be updated to / point to location where "new_node" is [...]

This would exactly describe call-by-reference, which - as Java does only call-by-value - does not happen.

The main difference between your first code snippet and the second one is: In the first example you reinitialized the parameter by assigning it a new reference. This will not be reflected in the calling function. In the second example you are dereferencing the parameter (the "." is also known as the dereference operator) working on the object at this reference. The calling function and the called function both have the same reference, thus both are working on the same object when dereferencing.

Have a look at the Wikipedia article about call-by-value.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top