Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么这个程序输出1?_Java_Oop - Fatal编程技术网

Java 为什么这个程序输出1?

Java 为什么这个程序输出1?,java,oop,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;

我看过这段代码,不明白为什么这个程序会打印
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);
    }
}

Java不是按引用传递的(引用是按值传递的),将
myObject
赋值给
null
并没有什么区别。它不是
final
也不是,因为在
foo()方法中它不是final。它打印1,因为您将
myObject
的引用传递到
foo()
并设置其字段。它仍然是一个可变对象,因此其值会更新

首先,在
foo(myObject)
中,我们给
final
分配了一些东西,这怎么可能呢

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

第二件事,在
foo()
完成后,我们将
myObject
设置为null,那么我们如何打印它呢

在您的代码中有两个独立的东西称为
myObject

  • main

  • foo

  • foo
    中的代码将参数设置为
    null
    ,但这对
    main
    中的变量没有任何影响。(事实上,
    foo
    不可能对
    main
    中的变量产生任何影响;Java是一种纯粹的传递值语言。正如您所演示的,
    foo
    所能做的,就是修改变量和参数引用的对象的状态,使用传递给它的对象引用作为参数。)

    让我们在
    foo
    中的这一行之前停止代码:

    myObject.myInt = 1;
    
    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 |−−−+ +−−−−−−−−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−−−−−−+ |变量“myObject”| foo可以更改 +−−−−−−−−−−−−−−−−−−−−−−+ *本州* 福改变不了这个−−>| 参考文献22458|−−−+ | +−−−−−−−−−−−−−−−−−−−−−−+ | v | +−−−−−−−−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−−−−−−+ +−−−>| MyClass类型的对象| |参数“myObject”||+−−−−−−−−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−−−−−−+ | | myInt:1| 福可以改变这一点−−−−>| 空的|−−−+ +−−−−−−−−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−−−−−−+
    注意
    foo
    如何更改对象的状态(
    myInt
    现在是
    1
    ),如何更改参数
    myObject
    (现在是
    null
    )中的值,但无法更改变量
    myObject
    中的值(原因有两个:它无法访问变量[Java是按值传递的],变量是
    final
    )。

    final
    只是指定对象本身不应更改-当与代码这样的类一起使用时,它只是阻止某人执行
    myObject=…
    。除非您标记了
    MyClass.myInt
    final,否则即使在赋值之后,您也可以为int赋值


    解决这个问题的方法是将
    myInt
    设为私有,并为其提供一个公共getter,防止它被修改(反射除外)

    ,因为
    myObject.myInt=1
    。你以为会是什么?@bradimus没那么简单。。。在print语句之前,对象被设置为null,这可能会给那些不熟悉Java的人带来混乱。你知道Java是如何将对象传递给其他方法的吗???@MatthewDiana,你是对的,那里存在潜在的混乱,所以我想你可能会更小心使用你的语言。设置为null的不是对象,而是对它的一个引用。但是myObject=null的可能重复出现在foo()的内部,这不是对final的一个辅助吗?@limitless否。这些是不同范围内的不同引用。@limitless仅适用于
    foo()
    的范围内。您没有设置在
    main
    中声明为final的
    myObject
    ,而是为
    foo
    方法设置参数
    myObject
    。 +−−−−−−−−−−−−−−−−−−−−−−+ | 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 |−−−+ +−−−−−−−−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−−−−−−+