4

I was trying to learn about binary trees and NullPointerExceptionwere coming. So I decided to write a little program to try to understand it. Here is the code:

public class Nulls
{
    static Node node;
    private class Node
    {
        int val;
        Node right;
        Node left;
    }
    public void init(Node n)
    {
        if(n==null)n=new Node();
    }
    public void print()
    {
         System.out.println(node);
    }
    public static void main(String[] args)
    {
        Nulls n=new Nulls();
        n.init(node);
        n.print();
    }
}

The output was null. If I understand properly, the node object was initialized and the output should be the object's toString() method. And as the print() method is executed after init(Node n), the output should not be null. What is the problem?

Daman Arora
  • 87
  • 2
  • 6

1 Answers1

6

The root cause is that in Java arguments are passed by value, which means, when you pass a (reference to) node n as an argument, you're actually passing a copy of the reference to that node, which is null at that time. Since you're changing the copy-reference, nothing is really assigned and the new Node that you create in the init is eligible to GC when init has done executing.

But that's easy to fix:

public class Nulls {

    static Node node;

    private class Node {
        int val;
        Node right;
        Node left;
    }

    public void init() {
        if(node==null) {
            node=new Node();
        }
    }

    public void print() {
        System.out.println(node);
    }

    public static void main(String[] args) {
        Nulls n=new Nulls();
        n.init();
        n.print();
    }
}
Nir Alfasi
  • 53,191
  • 11
  • 86
  • 129
  • A personal comment is for me to ask, is the reason that it's being passed as a reference to the object because it's static? Or is there more to it? – CoderMusgrove Feb 14 '15 at 03:59
  • 4
    @CoderMusgrove No, static/non-static has nothing to do with it. In Java everything is passed by value. The confusing part is that *references* are passed by value as well, meaning, when you pass a reference to an object, what is actually passed is a new reference that is pointing to the same object. If you use that new reference to change the object - you'll see the changes after you exit the method because the original reference is referring to the same object. – Nir Alfasi Feb 14 '15 at 04:04
  • (continue:) In our case the original reference was pointing to `null`, and what the OP tried to do was to change the reference *itself* which cannot be done when you pass-by-value. – Nir Alfasi Feb 14 '15 at 04:04
  • It's the same situation as `public void init(int i) {if(i == 0) i = 42;}` `public static void main(String[] args) {int x = 0; init(x); System.out.println(x); /* why is x still 0? */}` – user253751 Feb 14 '15 at 05:40