java - 为什么这个程序输出1?

标签 java oop

我看过这段代码,我不明白为什么这个程序会打印 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 to final, how is it possisble?

对象 不是finalmain 中的变量final .所以在 main ,如果您添加了 myObject = somethingElse;在设置其值的初始行之后,它不会编译,因为您不能将新值放入变量。这对变量引用的对象是否可变没有影响。

And the second thing, after foo() was done, we'll get myObject to be null, so how can we even print it?

有两个独立的东西叫myObject在你的代码中:

  1. main 中的一个变量

  2. 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/

相关文章:

java - 在 Java 中再次使用相同变量之前使变量为 null

java - Internet 连接更改广播未发生

java - java中基本数据格式转换

php - 如何使用 OOP 从另一个 .php 到另一个 .php 的类使用 $db?

java - 为什么应用于该对象的 System.out.println 会打印这个短语?

java - Heroku 仅适用于刷新

java - 排除基于 PropertyFileConfig 的 CDI Bean(DeltaSpike,WebSphere 8.5.5)

java - 我应该在域包中放入哪些类?

c++ - 继承和重载默认构造函数

c++ - 在 GLUT 中使用非成员方法作为回调