5
class prog {

      static String display(String s)
      {
         s = "this is a test";
         return s;
      }

   public static void main(String...args) {

     prog p = new prog();
     String s1 = "another";
     System.out.println(display(s1)); //Line 1
     System.out.println(s1);
   }
}

一个新手问题。

有人可以解释为什么 s1 没有更新为“这是一个测试”吗?

我认为在 Java 中,对象参数作为引用传递,如果是这种情况,那么我s1在第 1 行将 String 对象作为引用传递。

并且s1应该通过display()方法设置为“这是一个测试”。对吗?

4

5 回答 5

19

Java 始终是按值传递的。对于引用类型,它传递引用值的副本。

在你的

static String display(String s)
{
    s = "this is a test";
    return s;    
}

引用被重新分配,它的String s值被改变。被调用的代码不会看到这种变化,因为该值是一个副本。

使用Strings,很难表现出行为,因为它们是不可变的,但举个例子

public class Foo {
    int foo;
}

public static void main(String[] args) {
    Foo f = new Foo();
    f.foo = 3;
    doFoo(f);
    System.out.println(f.foo); // prints 19
}

public static void doFoo(Foo some) {
    some.foo = 19;
}

但是,如果你有

public static void doFoo(Foo some) {
    some = new Foo();
    some.foo = 19;
}

原件仍会显示3,因为您没有通过传递的引用访问对象,而是通过new引用访问它。


当然,您始终可以返回新引用并将其分配给某个变量,甚至可能与您传递给方法的变量相同。

于 2013-09-06T16:21:08.160 回答
3

String是按值传递的引用。您可以更改参考点的位置,但不能更改调用者的副本。如果对象是可变的,您可以更改它的内容。

简而言之,Java 总是通过 VALUE 传递,它从未做过任何其他事情。

于 2013-09-06T16:22:09.383 回答
2

正如其他人提到的那样,String s1 是按值传递的引用,因此您的方法中的 s1 引用仍然指向旧字符串。

我相信您想这样做以将返回的值分配回字符串 s1:

String s1 = "another";
s1 = display(s1);

System.out.println(display(s1))
于 2013-09-06T16:22:55.400 回答
0

实际上,在程序中,当您调用 display(s1) 时,您有两个引用字符串变量 s1 和 s。s1 和 s 都将引用字符串“另一个”。

但是在显示方法中,您将 s 的引用更改为指向另一个字符串“这是一个测试”,并且 s1 仍将指向“另一个”

现在 s 和 s1 正在参考两个不同的刺

display(s1) --> 保存 s 的引用,将打印“这是一个测试”

仅当您分配 s= display(s1) 时,两个变量都将引用相同的字符串

于 2013-09-06T17:15:01.097 回答
0

因为 String 是不可变的,所以如果您不将函数的返回值分配给 string.so 在您的问题中将 display(s1) 的值分配给 s,则不会发生更改。

s=display(s1);那么字符串s的值就会改变。

当我编写程序以获取一些排列字符串时,我也得到了未更改的值(虽然它没有给出所有排列,但这是例如回答你的问题)

这是一个例子。

import java.io.*;
public class MyString {
public static void main(String []args)throws IOException{
    BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
    String s=br.readLine().trim();
    int n=0;int k=0;
    while(n!=s.length()){
        while(k<n){
        swap(s,k,n);
        System.out.println(s);
        swap(s,k,n);
        k++;
        }
        n++;
    }


}
public static void swap(String s,int n1,int n2){
    char temp;
    temp=s.charAt(n1);
    StringBuilder sb=new StringBuilder(s);
    sb.setCharAt(n1,s.charAt(n2));
    sb.setCharAt(n2,temp);
    s=sb.toString();
}
}

但我没有从上面的代码中得到字符串的置换值。所以我将交换函数的返回值分配给字符串并得到了字符串的更改值。分配返回值后,我得到了字符串的置换值。

//import java.util.*;
import java.io.*;
public class MyString {
public static void main(String []args)throws IOException{
    BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
    String s=br.readLine().trim();
    int n=0;int k=0;
    while(n!=s.length()){
        while(k<n){
        s=swap(s,k,n);
        System.out.println(s);
        s=swap(s,k,n);
        k++;
        }
        n++;
    }


}
public static String swap(String s,int n1,int n2){
    char temp;
    temp=s.charAt(n1);
    StringBuilder sb=new StringBuilder(s);
    sb.setCharAt(n1,s.charAt(n2));
    sb.setCharAt(n2,temp);
    s=sb.toString();
    return s;
}
}
于 2017-11-28T20:03:34.203 回答