Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/386.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应用程序;真的;?_Java - Fatal编程技术网

为什么要打印此java应用程序;真的;?

为什么要打印此java应用程序;真的;?,java,Java,这是我的第一堂课Hello.java public class Hello { String name = ""; } 这是我的第二个类Test1.java public class Test1 { public static void main(String[] args) { Hello h = new Hello(); Test1 t = new Test1(); t.build(h); System

这是我的第一堂课Hello.java

public class Hello {
    String name = "";
}
这是我的第二个类Test1.java

public class Test1 {    
    public static void main(String[] args) {
        Hello h = new Hello();
        Test1 t = new Test1();
        t.build(h);
        System.out.println(h.name);
    }
    void build(Hello h){
        h.name = "me";
    }
}
当我运行Test1.java时,它会打印“我”。我想我理解,因为“参考转移”

这是我的第三个类Test2.java

public class Test2 {
    public static void main(String[] args) {
        Hello h = null;
        Test2 t = new Test2();
        t.build(h);
        System.out.println(h == null);
    }
    void build(Hello h){
        h = new Hello();
    }
}

当我运行Test2.java时,它会打印“true”,为什么?是否不再是“参考转移”?我很困惑。

因为h等于null。

Java总是通过值传递。当您有引用时,它只传递指向同一对象的引用副本。在您的情况下,只需将复制的引用重新路由到另一个对象。这就是为什么您的原始版本没有更改。

您可能知道,Java是按值调用的。传递引用时,该引用将被复制。可以肯定的是:复制的是引用本身,而不是引用的目标

让我们看一下您的第一个示例:调用
build()
时,将复制引用
h
。由于
h
build()
)中的副本不会在
build()
中的某个位置被覆盖,因此它总是指向原始
h
的内存位置。因此更改
h.name
会影响原始
h


示例2不同:引用
h
也会被复制。但是
h
build()
中被覆盖。结果是
build()
中的原始
h
h
指向不同的内存位置!
build()
中的
h
指向新生成的
Hello
对象,当返回方法
build()
后,该对象将被垃圾收集
h.name=“me”
更改
h
引用的对象。此更改将从引用同一对象的任何其他位置可见
h=newhello()
使h引用另一个(新)对象。此更改仅影响该特定变量h,而不影响以前引用同一对象的任何其他变量。

Mybe这解释了原因:

您有两个不同的变量
h
。第一个是本地的
main
。第二个是本地的
build

如果将
build
变量重命名为
x
,那么
main
中的
h
不受影响的原因应该很明显

编辑:


在这里您可以清楚地看到,
x
null
开头。然后
x
成为一个新对象。然后
x
死亡
h
不知道
x
生命中发生了什么。

在Test1.java中,当您将
Hello
object
h
传递到build()方法时,变量
main().h
build().h
指向内存中的同一个对象

i、 e.
main().h=build().h=>指向同一对象

但是在Test2.java中,即使您将
main().h
传递给build()方法,稍后在build方法内部,您将
build().h
重新初始化到一个新对象。但这不会影响
main().h

i、 e.
main().h!=build().h
//它们都指向不同的对象


这就是为什么
main()

在第一种情况下,您直接访问对象(堆中的内存)并更改一个值,在第二种情况下,引用将拥有新对象,直到方法结束。之后,它将不再可访问

    public static void main(String[] args){
           String str = null;
           System.out.println(getString(str)== null);
   }

    public static String getString(String s){
            s = new String();
            return s;
    }
上面的代码将打印为false,简单地说:

1) 首先创建一个变量“h”,并将其指向null

2) 当您使用“void build(Hello h)”方法时,您将创建一个新的variabel(也称为“h”),它将指向null(复制变量指向的指针)

3) 当您执行'h=new Hello()'时,您可以更改方法中的新'h'变量,使其指向Hello的新实例(new Hello())

名为“h”的原始变量不变


非常简单。

Java的可能重复项按值传递。Java按值传递引用。这些括号有多少?fromer lisp程序员?:-PHe询问为什么h等于null,即为什么在构建内部执行
h=new Hello()
不会影响main中的h。
    public static void main(String[] args){
           String str = null;
           System.out.println(getString(str)== null);
   }

    public static String getString(String s){
            s = new String();
            return s;
    }