5

我知道在 Java 中,一切都是按值传递的。但是对于对象来说,传递的是对对象的引用的值。这意味着有时可以通过参数更改对象,这就是为什么,我猜,人们说,永远不要修改参数。

但是在下面的代码中,发生了一些不同的事情。 s当您返回时inchangeIt()不会改变main()

public class TestClass {

    static String str = "Hello World";

    public static void changeIt( String s ) {
        s = "Good bye world";
    }

    public static void main( String[] args ) {
        changeIt( str );
        System.out.println( str );
    }
}

我猜——我想确认一下——当你说它s = "something"与说相同或等同时String s = new String("something")。这就是为什么s不改变?它是否在本地分配了一个全新的对象,一旦退出就会被丢弃changeIt()

4

3 回答 3

4

当您说 s = "something" 时,它与说 String s = new String("something") 相同或等效

是的,差不多。(尽管 JVM 可能会进行优化,以便多次使用的同一个字符串字面量引用同一个 String 对象)。

这就是为什么s不改变?它是否在本地分配了一个全新的对象,一旦退出 changeIt() 就会被丢弃

是的。正如您所说,Java 中的所有内容都是按值传递的,甚至是对对象的引用。因此,变量sin 与您在 main() 中使用的changeIt( String s )值不同str,它只是 changeIt 方法中的局部变量。将该引用设置为引用另一个对象不会影响changeIt.

请注意,在您将不同的对象分配给之前,输入方法时s引用的 String 对象仍然是相同的 StringstrchangeIt()s

您需要注意另一件事,那就是字符串是不可变的。这意味着您在字符串对象上调用的任何方法都不会更改该字符串。例如,s.toLowerCase()在您的 changeIt() 方法中调用也不会影响调用者。这是因为 String.toLowerCase() 不会改变对象,而是返回一个新的 String 对象。

于 2012-07-20T19:43:31.007 回答
3

当你写

s = "Good bye world";

您正在将值更改s为对新字符串的引用。您没有更改 . 引用的字符串的值s

于 2012-07-20T19:45:52.697 回答
0

是的,现在 'S' 指向范围仅限于该方法的全新对象。字符串可能不是理解传递值概念的完美示例。而不是字符串,让我们说传递一些可变对象引用并在方法内对分配的新对象进行更改。您在对象之外看不到它们。

public class MyMain {

    private static void testMyMethod(MyMain mtest) {
        mtest=new MyMain();
        mtest.x=50;
        System.out.println("Intest method"+mtest.x);
    }
     int x=10;
    public static void main(String... args)
    {
        MyMain mtest = new MyMain();
        testMyMethod(mtest);
        System.out.println("In main method: "+mtest.x);
    }
}

阅读此SO 讨论中的第二个答案。

于 2012-07-20T19:41:50.273 回答