如果 Java 是一种 "call-by-value" 语言那么为什么会这样?
If Java is a "call-by-value" language then why is this happening?
查看测试代码:
class Node
{
int num = 0;
}
class TestPassByReference
{
void increaseByOne(Node N)
{
N.num++ ;
}
public static void main(String args[])
{
Node N = new Node() ;
TestPassByReference T = new TestPassByReference() ;
T.increaseByOne(N) ;
System.out.println("num = "+N.num) ;
T.increaseByOne(N) ;
System.out.println("num = "+N.num) ;
T.increaseByOne(N) ;
System.out.println("num = "+N.num) ;
}
}
给出结果:
num = 1
num = 2
num = 3
这里的问题是,既然 Java
是 call by value
那么 Node
的 num
属性应该保持为 0。
我认为这是由于创建了一个对象 T
,该对象本应包含一个对象 N
。但是T
里面没有属性可以保存一个Node
类的对象。那么这是怎么发生的呢?
非常感谢任何帮助。
月亮。
Java 通过引用传递对象。 Node N
是一个对象。因此,当您执行 N.num++
时,您正在递增同一对象的整数。
在您的代码中,您有 class 节点的单个对象。
保存 num
的初始值为 0 的值,
当调用函数和增加 num
的值时,每次 num
的值都会增加,因为相同的节点 class 对象。其简单易懂的节点对象是 class 节点的实例,如果您创建另一个节点 class 对象,它将是 class 的不同实例。
class Node
{
int num = 0;
}
class TestPassByReference
{
void increaseByOne(Node N)
{
N.num++ ;
}
public static void main(String args[])
{
Node N1 = new Node() ;
Node N2 = new Node() ;
TestPassByReference T = new TestPassByReference() ;
T.increaseByOne(N1) ;
System.out.println("num = "+N1.num) ;
T.increaseByOne(N1) ;
System.out.println("num = "+N1.num) ;
T.increaseByOne(N2) ;
System.out.println("num = "+N2.num) ;
}
}
结果是:
num = 1
num = 2
num = 1
好吧,您正在创建 Node 和 TestPassByReference 的单个对象,因此 T 引用了您之前在云中创建的相同 Node 引用。因此,当您调用该方法时,相同的值会增加。
Java
是按值调用,因为 references
是按值传递。
这意味着您可以更改传递给 N
的对象的内部状态(例如,通过修改 num
字段的值)但您不能将 N
重新分配给新对象 (例如 N = null;
或 N = new Node();
).
class Node
{
int num = 0;
}
class TestPassByReference
{
void increaseByOne(Node N)
{
N.num++ ;
System.out.println("num value is:" + N.num);
}
void increaseByOneThenChange(Node N)
{
// increase by one as before
N.num++;
// change the reference to a new object
N = new Node();
System.out.println("num value is:" + N.num);
}
public static void main(String args[])
{
Node N = new Node() ;
TestPassByReference T = new TestPassByReference() ;
T.increaseByOne(N) ;
System.out.println("num = "+N.num) ;
T.increaseByOne(N) ;
System.out.println("num = "+N.num) ;
T.increaseByOne(N) ;
System.out.println("num = "+N.num) ;
// now try this method to see the difference
T.increaseByOneThenChange(N);
// N here is the original object, whose `num` value was incremented
// but the reference remains unchanged by the above method
System.out.println("num = "+N.num) ;
}
}
在第二种情况下,只有传递给方法的引用发生变化,因此仅在方法主体中可见(N
将不再引用原始对象),但原始对象仍然是一样。
查看测试代码:
class Node
{
int num = 0;
}
class TestPassByReference
{
void increaseByOne(Node N)
{
N.num++ ;
}
public static void main(String args[])
{
Node N = new Node() ;
TestPassByReference T = new TestPassByReference() ;
T.increaseByOne(N) ;
System.out.println("num = "+N.num) ;
T.increaseByOne(N) ;
System.out.println("num = "+N.num) ;
T.increaseByOne(N) ;
System.out.println("num = "+N.num) ;
}
}
给出结果:
num = 1
num = 2
num = 3
这里的问题是,既然 Java
是 call by value
那么 Node
的 num
属性应该保持为 0。
我认为这是由于创建了一个对象 T
,该对象本应包含一个对象 N
。但是T
里面没有属性可以保存一个Node
类的对象。那么这是怎么发生的呢?
非常感谢任何帮助。
月亮。
Java 通过引用传递对象。 Node N
是一个对象。因此,当您执行 N.num++
时,您正在递增同一对象的整数。
在您的代码中,您有 class 节点的单个对象。
保存 num
的初始值为 0 的值,
当调用函数和增加 num
的值时,每次 num
的值都会增加,因为相同的节点 class 对象。其简单易懂的节点对象是 class 节点的实例,如果您创建另一个节点 class 对象,它将是 class 的不同实例。
class Node
{
int num = 0;
}
class TestPassByReference
{
void increaseByOne(Node N)
{
N.num++ ;
}
public static void main(String args[])
{
Node N1 = new Node() ;
Node N2 = new Node() ;
TestPassByReference T = new TestPassByReference() ;
T.increaseByOne(N1) ;
System.out.println("num = "+N1.num) ;
T.increaseByOne(N1) ;
System.out.println("num = "+N1.num) ;
T.increaseByOne(N2) ;
System.out.println("num = "+N2.num) ;
}
}
结果是:
num = 1
num = 2
num = 1
好吧,您正在创建 Node 和 TestPassByReference 的单个对象,因此 T 引用了您之前在云中创建的相同 Node 引用。因此,当您调用该方法时,相同的值会增加。
Java
是按值调用,因为 references
是按值传递。
这意味着您可以更改传递给 N
的对象的内部状态(例如,通过修改 num
字段的值)但您不能将 N
重新分配给新对象 (例如 N = null;
或 N = new Node();
).
class Node
{
int num = 0;
}
class TestPassByReference
{
void increaseByOne(Node N)
{
N.num++ ;
System.out.println("num value is:" + N.num);
}
void increaseByOneThenChange(Node N)
{
// increase by one as before
N.num++;
// change the reference to a new object
N = new Node();
System.out.println("num value is:" + N.num);
}
public static void main(String args[])
{
Node N = new Node() ;
TestPassByReference T = new TestPassByReference() ;
T.increaseByOne(N) ;
System.out.println("num = "+N.num) ;
T.increaseByOne(N) ;
System.out.println("num = "+N.num) ;
T.increaseByOne(N) ;
System.out.println("num = "+N.num) ;
// now try this method to see the difference
T.increaseByOneThenChange(N);
// N here is the original object, whose `num` value was incremented
// but the reference remains unchanged by the above method
System.out.println("num = "+N.num) ;
}
}
在第二种情况下,只有传递给方法的引用发生变化,因此仅在方法主体中可见(N
将不再引用原始对象),但原始对象仍然是一样。