在下面的代码中,将调用methodA
,然后将methodB
的调用委托给methodB
,methodA
使用字符串文字“bbb”分配输入参数,但是,回到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");
}
}
,字符串文字不在那里,JLS的哪一部分定义了这种行为?
{{1}}
答案 0 :(得分:4)
这是传递值与传递引用问题。 Java仅通过值传递。当你打电话
methodB(a)
引用a
被复制;在methodB
的上下文中,a
是一个与methodA
中具有相同值的不同变量。因此,当您在methodB
中进行更改时,a
中的methodA
仍然指向原始字符串。
这里发挥的另一个问题是字符串是不可变的,所以一旦设置了String就不能改变它的值。来自文档。
字符串是不变的;他们的价值观无法改变 创建
你能做的是
a = methodB();
并在"bbb"
中返回methodB
。没有理由通过a
,因为你没有对它进行操作;我认为你只是试图在调用a
的上下文中尝试更改methodB
,这是你无法做到的。
最后,JLS的相关部分是8.4.1,其中说明了
当调用方法或构造函数(第15.12节)时,该值的值 实际参数表达式初始化新创建的参数 变量,每个声明的Type,在执行主体之前 方法或构造函数。出现在标识符中的标识符 DeclaratorId可以在方法体中用作简单名称或 构造函数引用形式参数。
答案 1 :(得分: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
}