Java浅层和深层复制JLS

Java浅层和深层复制JLS,java,deep-copy,shallow-copy,jls,Java,Deep Copy,Shallow Copy,Jls,可能重复: 在下面的代码中,methodA将被调用,然后它将调用委托给methodB,在这样做时,methodB将输入参数指定为字符串文字“bbb”,然而,回到methodA,字符串文字不在那里,JLS的哪个部分定义了这种行为 package sg.java.test2; public class TestApple { public static void main(String args[]){ methodA(); } public stati

可能重复:

在下面的代码中,
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");
    }
}

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

方法签名是以下内容的简写:

methodB() {
    String a = arguments[0];
i、 这是一个不同的参考。分配给“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
}

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

方法签名是以下内容的简写:

methodB() {
    String a = arguments[0];
i、 这是一个不同的参考。分配给“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
}

这是一个按值传递与按引用传递的问题。Java只是按值传递。当你打电话的时候

methodB(a)

引用
a
被复制;在
methodB
的上下文中,
a
是一个不同的变量,其值与
methodA
中的值相同。因此,当您在
methodB
中更改它时,
methodA
中的
a
仍然指向原始字符串

这里要考虑的另一个问题是字符串是不可变的,所以一旦设置了字符串,就不能更改它的值。从文件中

字符串是常量;它们的值在更改后不能更改 创造

你能做的就是

a=methodB()

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

最后,JLS的相关部分是

调用方法或构造函数时(§15.12) 实际参数表达式初始化新创建的参数 每个声明类型的变量,在执行 方法或构造函数。中显示的标识符 DeclaratorId可以在方法体中用作简单名称或 构造函数引用形式参数


这是一个按值传递与按引用传递的问题。Java只是按值传递。当你打电话的时候

methodB(a)

引用
a
被复制;在
methodB
的上下文中,
a
是一个不同的变量,其值与
methodA
中的值相同。因此,当您在
methodB
中更改它时,
methodA
中的
a
仍然指向原始字符串

这里要考虑的另一个问题是字符串是不可变的,所以一旦设置了字符串,就不能更改它的值。从文件中

字符串是常量;它们的值在更改后不能更改 创造

你能做的就是

a=methodB()

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

最后,JLS的相关部分是

调用方法或构造函数时(§15.12) 实际参数表达式初始化新创建的参数 每个声明类型的变量,在执行 方法或构造函数。中显示的标识符 DeclaratorId可以在方法体中用作简单名称或 构造函数引用形式参数


java是按值传递的该死!!对不起,意思是说不通过引用。。。修正了为什么a.foo从methofB回来后会给出一个“foo”。@chin因为
methodB
设置了a.foo='foo'@hvgotcodes因为我又犯了一个错误,输入了'foo'而不是'prop'。。。睡眠不足,咖啡喝得太少。java简直是一派胡言!!对不起,意思是说不通过引用。。。修正了为什么a.foo从methofB回来后会给出一个“foo”。@chin因为
methodB
设置了a.foo='foo'@hvgotcodes因为我又犯了一个错误,输入了'foo'而不是'prop'。。。睡眠不足,咖啡太少。另外,谢谢,如果我试图传递的参数不是一个字符串,并且是可变的,比如说一个普通的域对象,那么上面的情况还会是真的吗?正确。我为你的答案添加了一个示例。感谢buddy的提醒。另外,如果我试图传递的参数不是字符串,并且是可变的,比如说普通域对象,那么上面的结果仍然正确吗?正确。我给你的答案添加了一个例子。谢谢巴迪的提醒。