在Java中交换两个字符串,方法是将它们传递给实用程序函数,但不返回对象或使用包装类

8 java string pass-by-reference

我试图在Java中交换两个字符串.我从未真正理解"字符串是不可变的".我在理论上理解它,但我在实践中从未遇到过它.

此外,由于String是Java中的对象而不是基本类型,我不明白为什么以下代码两次打印相同的结果,而不是交换单词!

public static void main(String[] args)
{
    String s1 = "Hello";
    String s2 = "World";

    System.out.println(s1 + " " + s2);

    Swap(s1, s2);

    System.out.println(s1 + " " + s2);
}

public static void Swap(String s1, String s2)
{
    String temp = s1;
    s1 = s2;
    s2 = temp;
}
Run Code Online (Sandbox Code Playgroud)

我想要它打印

Hello World
World Hello
Run Code Online (Sandbox Code Playgroud)

但它是印刷品

Hello World
Hello World
Run Code Online (Sandbox Code Playgroud)

我认为s1和s2是引用,因此引用应该交换,新引用应分别指向另一个引用.我哪里错了?

Kon*_*lph 13

我认为s1和s2是引用,因此引用应该交换,新引用应分别指向另一个引用.

是.在本地内部 swap,这正是发生的事情.

但是,s1并且s2是传递给函数的引用的副本,因此效果仍然是本地的.请注意,它不是复制的字符串(因为String它是引用类型).但是引用复制了.

...并且由于参数引用总是在Java中复制,swap因此根据您的规范编写函数是非常简单的.

如果您在理解差异时遇到问题,请考虑以下事项:您想给朋友写一封信,以便将她的邮寄地址从地址簿复制到信封上.通过这个过程,你当然没有复制她的家(复制整个房子在实践中有点困难) - 你只复制了地址.

好吧,一个地址指的是她的家,所以它就像一个Java引用.


And*_*s_D 6

下面的代码是NoGo,永远不会实现这种反模式,永远不会改变不可变对象的私有最终内部.不要责怪我表现出这种黑客行为,因为甲骨文公司没有放弃它而责怪他.

但是,如果有一天你找到一些代码可以工作:

 String a = "Hello";
 String b = "World";
 String c = "World";
 swap(a,b);
 System.out.printf("%s %s%n", a,b);  // prints: World Hello !!

 System.out.println(c);  // Side effect: prints "Hello" instead of "World"....
Run Code Online (Sandbox Code Playgroud)

执行情况swap可能如下:(请自行承担风险,我警告过你!)

 private void swap(String a, String b) {
   try {
     Field value = String.class.get("value");
     value.setAccessible(true);    // this should be forbidden!!

     char[] temp = value.get(a);
     value.set(a, value.get(b));
     value.set(b, temp);           // Aaargh, please forgive me
   } catch(Exception e) {
     e.printStackTrace(e);
   }
 }
Run Code Online (Sandbox Code Playgroud)