首先,在foo(myObject)
我们正在给final
分配一些东西,它是如何可能的?
的对象不final
,在main
的可变是final
。因此,在main
中,如果您在设置其值的初始行之后添加了myObject = somethingElse;
,它将无法编译,因为您无法在变量中输入新值。这对变量引用的对象是否可变是没有影响的。
第二件事,foo()
已完成后,我们会得到myObject
是空的,所以我们怎么能打印呢?
有两个独立的东西在你的代码中调用myObject
:
中的变量main
在中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 |−−−+ +−−−−−−−−−−−−−−−−−−−−−−−−+
+−−−−−−−−−−−−−−−−−−−−−−+
...其中“ Ref22458“只是指向您在main
中创建的对象的对象引用值的名称。
一旦我们执行在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
)。
因为'myObject.myInt = 1'。你期望它是什么? – bradimus
@bradimus它不那么简单......在打印语句之前将对象设置为null,这可能会导致不熟悉Java的人员感到困惑。 –
你知道java如何将对象传递给另一个方法吗? –