为什么这个java应用程序打印“true”?

时间:2010-05-12 11:30:23

标签: java

这是我的第一个Hello.java类

public class Hello {
    String name = "";
}

这是我的第二个Class 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时,它会打印“我”。我想我理解,因为“参考转移”。

这是我的第三个Class 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”,为什么?是不是“参考转移”?我很困惑。

9 个答案:

答案 0 :(得分:7)

您可能知道,Java是按值调用的。 Wenn你传递了一个引用,该引用被复制了。确定:引用本身和引用的目标被复制。

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

示例2不同:参考h也会被复制。但是h会覆盖build()。结果是h中的原始hbuild()指向不同的内存位置! h中的build()指向新生成的Hello对象,在返回方法build()后将对其进行垃圾回收。

答案 1 :(得分:3)

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

答案 2 :(得分:1)

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

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

编辑:

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 x){
        x = new Hello();
    }
}

您可以清楚地看到,xnull开头。然后x成为新对象。然后x死了。 hx生活中发生的事情一无所知。

答案 3 :(得分:0)

h.name = "me"更改h引用的对象。从引用相同对象的任何其他位置可以看到此更改。 h = new Hello()使h引用另一个(新)对象。此更改仅影响特定变量h - 而不影响先前引用同一对象的任何其他变量。

答案 4 :(得分:0)

答案 5 :(得分:0)

在Test1.java中,当您将Hello对象h传递给build()方法时,变量main().hbuild().h指向内存中的同一对象。 / p>

即。 main().h = build().h => pointing same object

但是在Test2.java中,即使您将main().h传递给build()方法,稍后在内部构建方法中,您也会将build().h重新分配给新对象。但这不会影响main().h

即。 main().h != build().h //他们都指出了不同的对象。

这就是main().h仍包含null并且您的程序打印为true的原因。

答案 6 :(得分:0)

首先,您需要了解Object和Reference之间的区别。

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

    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

答案 7 :(得分:0)

说实话:

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

2)当你进入方法“void build(Hello h)”时,你创建一个新的variabel(也称为'h'),它被指向null(指向变量指向的指针是COPIED)。

3)当你执行'h = new Hello()'时,你将方法中的新'h'变量更改为指向Hello的新实例(new Hello())。

名为'h'的原始变量未更改。

简单如馅饼。

答案 8 :(得分:-1)

因为h等于null。