我知道在Java中,一切都是按值传递的。但对于对象,它是传递的对象的引用值。这意味着有时一个对象可以通过参数进行更改,这就是为什么人们会说,永远不要修改参数。
但是在下面的代码中,会发生一些不同的事情。当你回到s
时,changeIt()
中的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()
,它就会被丢弃?
答案 0 :(得分:4)
当你说s =“something”时,它与String s = new String(“something”)相同或相当
是的,差不多。 (尽管JVM可能会进行优化,以便多次使用相同的字符串文字引用相同的String对象。)
这是为什么s不会改变?它是否在本地分配了一个全新的对象,一旦退出changeIt()
就会被抛弃
是。正如你所说,Java中的所有内容都是通过值传递的,甚至是对象的引用。因此s
中的变量changeIt( String s )
与您在main()中使用的str
不同,它只是changeIt方法中的局部变量。
将该引用设置为引用另一个对象不会影响changeIt
的调用者。
请注意,String对象s
引用的仍然是str
在将changeIt()
方法分配给s
之前输入s.toLowerCase()
方法时所引用的字符串/ p>
还有一件事你需要注意,那就是字符串是不可变的。这意味着您在字符串对象上调用的方法都不会更改该字符串。例如在changeIt()方法中调用{{1}}也不会影响调用者。那是因为String.toLowerCase()不会改变对象,而是返回一个新的String对象。
答案 1 :(得分:3)
写作时
s = "Good bye world";
您正在将s
的值更改为对新字符串的引用。您没有更改s
引用的字符串的值。
答案 2 :(得分: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 discussion中的第二个答案。