0

可能重复:
Java 通过引用传递问题

在我下面的代码中,methodA将被调用,然后将调用委托给methodB,在此过程中,methodB使用字符串文字“bbb”分配输入参数,但是,回到methodA,字符串文字不存在,JLS 的哪个部分定义了这个行为?

package sg.java.test2;

public class TestApple {
    public static void main(String args[]){
        methodA();
    }

    public static void methodA(){
        String a = null; 

        methodB(a);

        System.out.println(a);
    }

    public static void methodB(String a){
        a = new String("bbb");
    }
}
4

2 回答 2

4

这是按值传递与按引用传递的问题。Java 仅按值传递。你打电话时

methodB(a)

引用a被复制;在 的上下文中methodBa是一个不同的变量,其值与 中的相同methodA。所以当你把它改成 in 时methodBainmethodA仍然指向原来的 String。

这里涉及的另一个问题是字符串是不可变的,因此一旦设置了字符串,就无法更改它的值。从文档。

字符串是常量;它们的值在创建后无法更改。

你能做的是

a = methodB();

并返回"bbb"methodB没有理由通过a,因为您没有对其进行操作;我认为您这样做只是为了尝试a在调用的上下文中进行更改methodB,而这是您无法做到的。

最后,JLS 的相关部分是8.4.1,它说

当调用方法或构造函数时(第 15.12 节),实际参数表达式的值会在执行方法或构造函数的主体之前初始化新创建的参数变量(每个声明的类型)。出现在 DeclaratorId 中的 Identifier 可以用作方法体或构造函数的简单名称,以引用形式参数。

于 2011-09-21T16:01:39.710 回答
2

Java 是按值传递,而不是按引用传递。

方法签名是这个的简写:

methodB() {
    String a = arguments[0];

即它是一个差异参考。当您分配给“a”时,您分配给作为方法签名的一部分创建的引用“a”,而不是您在包含对 methodB() 调用的代码块中声明的“a”。

但是,如果它是一个对象,您可以修改该值。

class MyObj {
    String prop;
    public MyObj(String s) { prop = s; }
    public MyObj() { }
}

public void methodB(MyObj o) {
    o.prop = "foo";
}

public void methodA() {
    MyObj a = new MyObj();
    System.out.println(a.prop); // null
    methodB(a);
    System.out.println(a.prop); // foo
}
于 2011-09-21T16:01:28.880 回答