2

I'm not terribly familiar with Java, I'm fiddling with a simple binary tree and ran into something that I dont understand...

in the following snippet, Add() passes AddHelper() a number and a reference to the root node, mRoot. However, mRoot is always null, even after the first call to AddHelper()

If, however, I change I change AddHelper() such that it uses mRoot directly (instead of being passes in by reference), then it works... I dont understand why/how this would be any different, functionally.

Node mRoot;

public void Add( int num ) {
    AddHelper(num, mRoot);
}

private void AddHelper( int num, Node node ){
    // if I change 'node' to 'mRoot', it works. why?
    if ( node == null ) {
        node = new Node(num);
    }
    else {
        ...
    }
0

2 Answers 2

2

assuming you have declared mRoot as a Node in your class already let me answer your question.

java is always pass by value when you pass mRoot to your method you are passing bytes that are referring the object in the heap. for example when you do this with a primitive variable

int i =5;
int j=i;

the bytes stored in i is transferred to j. similarly when you do this

Object obj = new Object();
Object newObj = obj;

the bytes stored in the reference variable obj is getting transferred to the reference newObj. as obj holds the reference to the Object instance the same reference is held by newObj.

you can see that

i = 5;
j=i;
j=10; // this doesn't change the i value

same way

obj = new Object();
newObj  = obj;
newObj = new Object(); // this doesn't change the obj

hope you understood.

EDIT:

to answer your question in the comment, consider the following code.

class Sample {
  Object originalObj;
  public static void main(String[] args) {
   System.out.println(originalObj); // prints null

   tryToCreateInstance(originalObj);
   System.out.println(originalObj); // still prints null

   createInstance(originalObj)
   System.out.println(originalObj); // prints the object hashcode

  originalObj = returnInstance(originalObj);//returns the same reference as originalObj
                                          //is already initialized, if it had been null
                                          // this would have returned a new object
   System.out.println(originalObj); // prints the object hashcode
  }

  public void tryToCreateInstance(Object obj1){
    if(obj1==null) {
       obj1 = new Object(); // relate this with my answer above 
                            // this wont change what originalObj refers
    }
  }

  public void createInstance(){
    if(obj==null) {
       originalObj = new Object(); // refers to the instance variable originalObj
                                   // hence will affect what originalObj refers
    }
  }

  public Object returnInstance(Object obj1) {
    if(obj1==null) {
       return new Object(); // returns a new object
    }
    else {
      return obj1;
    }
  }

}
Sign up to request clarification or add additional context in comments.

6 Comments

I see... so the whole thing fell apart because I was passing a null object, that by definition points to nothing, and I cannot assign something to nothing. Yes?
no dats not d fact. you can assign an object to a null reference. check my edited answer
But you still cannot assign anything to originalObj without assigning an object to it explicitly, that's what I meant. If originalObj is null when it is passed in as a parameter, you cannot assign an object to originalObj as a parameter, it remains null. You must in some way have "originalObj = something".
you are right now... :) glad you understood it.. but i cannot assign assign something to nothing is not right as you can assign an object to a reference that is null.
sure, I probably could have worded that better :P Thanks!
|
2

This is because you are not setting mRoot in your first case. Even though you are setting a node to new Node(num);, you are not setting mRoot. To set mRoot:

if ( node == null ) {
        node = new Node(num);
        this.mRoot = node; //depending on your logic
    }
    else {
        ...
    }

Jave is pass by value always. For example, mRoot points to Object X. When you pass mRoot to AddHelper, now node will point to Object X. And then you re-initialize node to new Object (say Object Y). But the previous mRoot still points to Object X.

Hence you need to set mRoot back to Object Y.

When we say pass by value, for primitives the value is copied. But in case of Objects, the object reference is copied (but not the object is duplciated). So if you pass a String reference to a function, the function argument will point to the same String only (as it has copied the object reference which can be though of as a pointer)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.