10

我研究过 java 是通过引用传递的,但是当我执行以下代码时,字符串没有在 main 方法中交换,为什么?

static void swap(String s1, String s2){
    String temp = s1;
    s1=s2;
    s2=temp;
}

public static void main(String[] args) {
    String s1 = "Hello", s2 = "world";
    swap(s1, s2);
    System.out.println(s1 + s2);
}
4

8 回答 8

11

你研究了错误的来源。Java 是按值传递的。是您可以研究的更多来源。从这里您可以找到与您的示例类似的讨论。

于 2012-07-28T09:51:12.643 回答
8

1.首先也是最重要的,Javapass by Value.(即Pass by Copy)。

2. reference Not the Object传递给方法。

例如:

public class Test{

        private String x;

            public void go(String s){

                this.x = s;

           }

         public static void main(String[] args){

                  Test t = new Test();

                  String a = new String("Bye");

                  t.go(a);


             }
      }

上面的代码不是为了展示交换是如何完成的,而是为了让一个重要的点可见。

  • 通过将一个参数“a”(它是一个字符串类型)传递给参数“s”(它也是一个go(String s)字符串类型)来调用方法时,它只是由值/副本传递的引用。 Object reference variable Object reference variable

  • 对 进行的任何更改 reference 都会影响堆上的 String 对象,而不是 the reference

于 2012-07-28T11:08:20.520 回答
2

传递给方法的是对象引用的副本。因此,无论您重新分配引用多少次,原始引用都不会受到影响。

试试这个:

static void reverse(StringBuilder builder) {
    builder.reverse();
}

public static void main(String[] args) {
    StringBuilder builder = new StringBuilder("hello");
    System.out.println(builder);
    reverse(builder);
    System.out.println(builder);
}

但是,下面的方法不会对传入的原始对象产生任何影响。

static void swap(StringBuilder builder) {
    builder = null;
}
于 2012-07-28T09:51:08.293 回答
2

Java 按值传递引用;在被调用的方法中交换引用对调用者没有影响。您的字符串是不可变的,因此您无法swap在调用者可见的方法中对它们执行任何操作。

但是,如果您传递可变对象,您将看到对它们所做的更改swap将反映在原始对象中:

public static void main(String[] args) {
    String a[] = {"hello", "world"};
    swap(a);
    System.out.println(a[0] + " " + a[1]);
}
static void swap(String[] a) {
    String t = a[0];
    a[0] = a[1];
    a[1] = t;
}

这是可行的,因为数组是可变的(即可以对其状态进行更改),并且因为对原始对象的引用被传递给被调用的函数(按值)。当swap修改其内容a时,调用者中的内容a也会被修改,因为它是同一个对象。

于 2012-07-28T09:51:31.943 回答
1

Java 总是按值传递引用。阅读此答案以获取更多详细信息。但是,您可以通过数组或包装类交换两个字符串。


编辑:

@dasblinkenlight 展示了如何使用数组来交换两个字符串,这里是一个使用包装类的例子:

public class WrapperString
{
    public String text;

    public WrapperString(String text){this.text = text}

    @Override
    public String toString(){return text;}
}

public static void swap(WrapperString a, WrapperString b)
{
    String temp = a.text;
    a.text = b.text;
    b.text = temp;
}

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

    swap(s1, s2);
    System.out.println(s1.text + s2.text);
    // or System.out.println(s1 + s2); since we've already overridden toString()
}

输出:

WorldHello
于 2012-07-28T09:55:20.763 回答
0
public static void swap(SwapDate[] t)
    {
     SwapDate temp;;
      temp=t[0];
       t[0]=t[1];
       t[1]=temp;
    }




       public static void main(String args[])throws Exception{

          SwapDate t[]=new SwapDate[5];
           t[0]=new SwapDate(20,8,2015);
           t[1]=new SwapDate(8,8,2015);

           System.out.println("(First object)Account Opnening date :"+" "+t[0].date);
           System.out.println("(second object)Account Opnening date :"+" "+t[1].date);


           swap(t);
           System.out.println("After Swap");

           System.out.println("(First object)Account Opnening date :"+" "+t[0].date);
           System.out.println("(second object)Account Opnening date :"+" "+t[1].date);


           }
于 2015-06-03T11:16:17.710 回答
0

Java 是严格按值传递的。

让我们从解释的角度修改您的代码如下

static void swap(String str1, String str2){
String temp = str1;
str1=str2;
str2=temp;
}

public static void main(String[] args) {
String s1 = "Hello", s2 = "world";
swap(s1, s2);
System.out.println(s1 + s2);

}

S1 和 S2 是保存字符串对象地址的引用。例如: S1=123 , S2= 234

当我们调用 swap 方法时,会创建 S1 和 S2 的副本并将其分配给 str1 和 str2。

这将是 str1=123 和 str2=234。

Swap 方法只会交换 str1 和 str2 中存在的值。(str1=234 str2=123) 而 S1 和 S2 仍然指向相同的内存位置。

这就是为什么交换没有反映在 main 方法中的原因。

于 2017-06-01T06:49:49.903 回答
-2

我们可以交换对象。很简单。只需使用一个虚拟对象来交换两个对象。

示例如下:

    Employee e1=new Employee();
    Employee e2=new Employee();
    e1.setName("e1");
    e2.setName("e2");   
    System.out.println(e1);
    System.out.println(e2);
    Employee temp= new Employee();
    temp=e1;
    e1=e2;
    e2=temp;
于 2014-04-13T19:39:33.253 回答