我看过这段代码,我不明白为什么这个程序会打印 1
。
首先,在 foo(myObject)
中,我们正在为 final 赋值,这怎么可能?
第二件事,在 foo()
完成后,我们将 myObject
设为 null,那么我们如何打印它呢?
public class MyClass {
private int myInt;
public static void foo(MyClass myObject) {
myObject.myInt = 1;
myObject = null;
}
public static void main(String[] args) {
final MyClass myObject = new MyClass();
myObject.myInt = 2;
foo(myObject);
System.out.println(myObject.myInt);
}
}
最佳答案
First of all, in
foo(myObject)
we are assigning something tofinal
, how is it possisble?
对象 不是final
,main
中的变量是final
.所以在 main
,如果您添加了 myObject = somethingElse;
在设置其值的初始行之后,它不会编译,因为您不能将新值放入变量。这对变量引用的对象是否可变没有影响。
And the second thing, after
foo()
was done, we'll getmyObject
to be null, so how can we even print it?
有两个独立的东西叫myObject
在你的代码中:
main
中的一个变量foo
中的一个参数
您在 foo
中的代码将参数设置为null
,但这对 main
中的变量没有任何影响。 . (事实上 , foo
不可能对 main
中的变量产生任何影响;Java 是一种纯粹的按值传递语言。正如您所展示的,所有 foo
可以做的就是修改状态变量和参数都引用的对象,使用传递给它的对象引用作为参数。)
让我们在 foo
中这一行之前停止您的代码:
myObject.myInt = 1;
这是我们内存中的内容(省略了一些细节和无关紧要的内容):
+−−−−−−−−−−−−−−−−−−−−−−+ | variable "myObject" | foo can change the +−−−−−−−−−−−−−−−−−−−−−−+ *state* of this foo can't change this−−>| Ref22458 |−−−+ | +−−−−−−−−−−−−−−−−−−−−−−+ | v | +−−−−−−−−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−−−−−−+ +−−−>| object of type MyClass | | parameter "myObject" | | +−−−−−−−−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−−−−−−+ | | myInt: 2 | foo can change this−−−−>| Ref22458 |−−−+ +−−−−−−−−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−−−−−−+
...where "Ref22458" is just a name for the value of the object reference that points to the object you created in main
.
Once we execute the two lines in foo
:
myObject.myInt = 1;
myObject = null;
我们在内存中有这个:
+−−−−−−−−−−−−−−−−−−−−−−+ | variable "myObject" | foo can change the +−−−−−−−−−−−−−−−−−−−−−−+ *state* of this foo can't change this−−>| Ref22458 |−−−+ | +−−−−−−−−−−−−−−−−−−−−−−+ | v | +−−−−−−−−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−−−−−−+ +−−−>| object of type MyClass | | parameter "myObject" | | +−−−−−−−−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−−−−−−+ | | myInt: 1 | foo can change this−−−−>| null |−−−+ +−−−−−−−−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−−−−−−+
注意如何 foo
可以更改对象的状态(myInt
现在是 1
),并且可以更改参数 myObject
中的值(现在是 null
),但无法更改 变量 myObject
中的值(有两个原因:它无法访问变量 [Java 是按值传递],并且变量是 final
)。
关于java - 为什么这个程序输出1?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38726615/