Java传递值 - 你能解释一下吗?

Pet*_*ete 2 java reference

我读了这篇优秀的文章,这是有道理的:Java严格按价值传递; 当一个对象是一个参数时,该对象的引用按值传递.

但是,我完全混淆了为什么以下代码段可能会起作用. Foo有一个String成员变量a,它是不可变的,每次都需要刻录.第一种刻录方法(注释掉)应该可以正常工作.第二个方法设置了a对传递的值的引用.如果newstr是临时变量,它应该不起作用.预期的输出结果是:

Totally temp
NULL
Run Code Online (Sandbox Code Playgroud)

但是,我明白了

Totally temp
Totally temp
Run Code Online (Sandbox Code Playgroud)

为什么?临时变量引用仍然很好,这只是纯粹的运气吗?

public class Foo {
    String a;
    public Foo(){}
    public void burna(String newstr){
           // a = new String(newstr);
           a = newstr; /*this should not work: */ 
        }
}

public class foobar {
    Foo m_foo;
    public foobar(){};
    public void dofoo(){
        String temp = new String("Totally temp\n");
        m_foo.burna(temp);
        System.out.print(m_foo.a);
    }

}

 public static void main(String[] args) {
        Foo myfoo = new Foo();
        foobar myfoobar = new foobar();

        myfoobar.m_foo = myfoo;
        myfoobar.dofoo();
        System.out.print(myfoo.a);

    }
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 11

Foo有一个String成员变量a,它是不可变的,每次都需要刻录.

不,它没有:它没有标记为final:

public class Foo {
    String a;
    ...
}
Run Code Online (Sandbox Code Playgroud)

变量是完全可变的 - 您可以随时更改它以引用不同的字符串,这是您在burna方法中执行的操作.

我目前没有看到为什么你认为这不起作用:

public void burna(String newstr){
    a = newstr; /*this should not work: */ 
}
Run Code Online (Sandbox Code Playgroud)

这就是设定anewstr-这是一个字符串(或空)的引用.这就是它所做的一切.我不确定你在变量中"燃烧"是什么意思.

您正在调用burna并传入一个带有文本"Totally temp \n"的a字符串的引用- 因此设置为对该字符串的引用.

你是什​​么意思"如果它newstr是一个临时变量,它应该不起作用." 没有"临时变量"这样的东西.有一个局部变量 - 但是一个对象不会因为引用它的变量超出范围而被销毁.那令你困惑的是什么?

你的程序有几件事情 - 这个foobar课程在理解方面可能没有帮助你.您是否可以尝试将代码简化到令您感到困惑的程度,但是进展较少?然后我们可以更准确地隔离混淆的来源.

  • @Will A:我更喜欢将它们视为值,恰好是引用.这与原始类型更加一致 - 赋值只是将RHS中的值复制到LHS上的变量.很好,很简单. (3认同)