我对Java并不十分熟悉,我正在摆弄一个简单的二叉树,遇到了一些我不理解的东西......
在以下代码段中,Add()
传递AddHelper()
个数字和对根节点mRoot的引用。但是,即使在第一次调用AddHelper()
但是,如果我改变,我改变AddHelper()
使得它直接使用mRoot(而不是通过引用传入),那么它可以工作......我不明白为什么/如何会有所不同,功能上。
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)
这是因为您没有在第一种情况下设置mRoot
。即使您将node
设置为new Node(num);
,也不会设置mRoot
。设置mRoot:
if ( node == null ) {
node = new Node(num);
this.mRoot = node; //depending on your logic
}
else {
...
}
Jave总是以值传递。例如,mRoot
指向对象X.当您将mRoot
传递给AddHelper
时,现在node
将指向对象X.然后您重新初始化{{1}到新的对象(比如对象Y)。但是之前的node
仍指向对象X.
因此,您需要将mRoot
设置回对象Y.
当我们说通过值时,对于基元,值被复制。但是对于Objects,会复制对象引用(但不会复制对象)。因此,如果将String引用传递给函数,则函数参数将仅指向相同的String(因为它复制了可以作为指针的对象引用)
答案 1 :(得分:2)
假设您已在课堂上宣布mRoot
为Node
已让我回答您的问题。
mRoot
传递给您的方法时,java总是按值传递,您传递的是引用堆中对象的字节。例如,当您使用原始变量
执行此操作时int i =5;
int j=i;
i
中存储的字节将传输到j
。同样,当你这样做时
Object obj = new Object();
Object newObj = obj;
存储在引用变量obj
中的字节将转移到引用newObj
。因为obj持有对Object
实例的引用,newObj
保持相同的引用。
你可以看到
i = 5;
j=i;
j=10; // this doesn't change the i value
同样的方式
obj = new Object();
newObj = obj;
newObj = new Object(); // this doesn't change the obj
希望你理解。
修改强>
在评论中回答您的问题,请考虑以下代码。
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;
}
}
}