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 {
...
}
2 Answers 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;
}
}
}
6 Comments
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)