如果 Java 是一种“按值调用”语言,那么为啥会发生这种情况?
Posted
技术标签:
【中文标题】如果 Java 是一种“按值调用”语言,那么为啥会发生这种情况?【英文标题】:If Java is a "call-by-value" language then why is this happening?如果 Java 是一种“按值调用”语言,那么为什么会发生这种情况? 【发布时间】:2017-08-07 05:57:18 【问题描述】:查看测试代码:
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
类似对象的属性。那么这是怎么回事呢?
非常感谢任何帮助。
月亮。
【问题讨论】:
你看到了吗:***.com/questions/40480/…? N 是按值调用的。当您使用点引用该值时,您将复制的值保留为对象引用并引用该对象。这在其他语言中称为指针。 Is Java "pass-by-reference" or "pass-by-value"?的可能重复 【参考方案1】:Java 通过引用传递对象。 Node N
是一个对象。因此,当您执行 N.num++
时,您将增加同一个对象的整数。
【讨论】:
【参考方案2】: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
将不再在此处引用原始对象),但原始对象保持不变。
【讨论】:
【参考方案3】:在您的代码中,您有一个 Node 类的 Object 。
保持num
的值,初始值为0,
并且当调用函数并增加num
的值时,每次num
的值都会增加,因为相同的Node 类对象。其简单易懂的节点对象是类 Node 的实例,如果您创建另一个 Node 类对象,它将是不同的类实例。
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
【讨论】:
【参考方案4】:好吧,您正在创建 Node 和 TestPassByReference 的单个对象,因此 T 引用了您之前在云中创建的相同 Node 引用。所以当你调用方法时,相同的值是递增的。
【讨论】:
以上是关于如果 Java 是一种“按值调用”语言,那么为啥会发生这种情况?的主要内容,如果未能解决你的问题,请参考以下文章
如果 Java 是强类型的,那么为啥这段代码会编译? [关闭]