Java和按引用传递
我对Java不是很熟悉,我在摆弄一个简单的二叉树,遇到了一些我不懂的东西 在下面的代码段中,Java和按引用传递,java,Java,我对Java不是很熟悉,我在摆弄一个简单的二叉树,遇到了一些我不懂的东西 在下面的代码段中,Add()传递一个数字和对根节点mRoot的引用。但是,即使在第一次调用AddHelper() 但是,如果我更改I changeAddHelper()使它直接使用mRoot(而不是通过引用传入),那么它就可以工作了。。。我不明白这在功能上有什么不同 Node mRoot; public void Add( int num ) { AddHelper(num, mRoot); } private
Add()
传递一个数字和对根节点mRoot的引用。但是,即使在第一次调用AddHelper()
但是,如果我更改I changeAddHelper()
使它直接使用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 {
...
}
这是因为您在第一种情况下没有设置
mRoot
。即使您正在将节点设置为新节点(num)代码>,您没有设置mRoot
。要设置mRoot,请执行以下操作:
if ( node == null ) {
node = new Node(num);
this.mRoot = node; //depending on your logic
}
else {
...
}
哈维总是被价值观所忽略。例如,mRoot
指向对象X。当您将mRoot
传递给AddHelper
时,现在节点将指向对象X。然后您将节点重新初始化为新对象(比如对象Y)。但是前面的mRoot
仍然指向对象X
因此,您需要将mRoot
设置回对象Y
当我们说“按值传递”时,对于基本体,值被复制。但对于对象,将复制对象引用(但不会复制对象)。因此,如果将字符串引用传递给函数,函数参数将仅指向同一字符串(因为它复制了对象引用,对象引用可以被视为指针)这是因为在第一种情况下没有设置mRoot
。即使您正在将节点设置为新节点(num)代码>,您没有设置mRoot
。要设置mRoot,请执行以下操作:
if ( node == null ) {
node = new Node(num);
this.mRoot = node; //depending on your logic
}
else {
...
}
哈维总是被价值观所忽略。例如,mRoot
指向对象X。当您将mRoot
传递给AddHelper
时,现在节点将指向对象X。然后您将节点重新初始化为新对象(比如对象Y)。但是前面的mRoot
仍然指向对象X
因此,您需要将mRoot
设置回对象Y
当我们说“按值传递”时,对于基本体,值被复制。但对于对象,将复制对象引用(但不会复制对象)。因此,如果将字符串引用传递给函数,函数参数将只指向同一字符串(因为它复制了对象引用,对象引用可以被视为指针)假设您已将mRoot
声明为类中的节点,我来回答您的问题
java总是按值传递当您将mRoot
传递给您的方法时,您正在传递引用堆中对象的字节。例如,当您使用基元变量执行此操作时
int i =5;
int j=i;
存储在i
中的字节被传输到j
。同样,当你这样做的时候
Object obj = new Object();
Object newObj = obj;
存储在参考变量obj
中的字节将被传输到参考newObj
。当obj持有对对象的引用时,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;
}
}
}
假设您已经将mRoot
声明为类中的节点
,那么让我回答您的问题
java总是按值传递当您将mRoot
传递给您的方法时,您正在传递引用堆中对象的字节。例如,当您使用基元变量执行此操作时
int i =5;
int j=i;
存储在i
中的字节被传输到j
。同样,当你这样做的时候
Object obj = new Object();
Object newObj = obj;
存储在参考变量obj
中的字节将被传输到参考newObj
。当obj持有对对象的引用时,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;
}
}
}
我懂了。。。所以整个过程都崩溃了,因为我传递了一个空对象,根据定义,它指向nothing,而我不能为nothing赋值。是吗?不,这不是事实。可以将对象分配给空引用。检查我编辑的回答,但如果不明确地为originalObj分配对象,您仍然无法为它分配任何内容,这就是我的意思。如果originalObj作为参数传入时为null,则不能将对象作为参数分配给originalObj,它将保持null。你必须以某种方式拥有“originalObj=something”。你现在是…:)很高兴你能理解。。但是我不能将某物赋值给nothing是不对的,因为你可以将一个对象赋值给一个空的引用。当然,我可能可以用更好的措辞:P谢谢!我懂了。。。所以整个过程都崩溃了,因为我传递了一个空对象,根据定义,它指向nothing,而我不能为nothing赋值。是吗?不,这不是事实。可以将对象分配给空引用。检查我编辑的回答,但如果不明确地为originalObj分配对象,您仍然无法为它分配任何内容,这就是我的意思。如果originalObj作为参数传入时为null,则不能将对象作为参数分配给originalObj,它将保持null。你必须以某种方式拥有“originalObj=something”。你现在是…:)很高兴你能理解。。但是我不能将某物赋值给nothing是不对的,因为你可以将一个对象赋值给一个空的引用。当然,我可能可以用更好的措辞:P谢谢!