Java字符串值的功能发生了变化

时间:2010-08-15 05:57:33

标签: java string function pass-by-reference

我有这个非常尴尬的问题......

void changeString(String str){
    str = "Hello world":
}

main(){
    String myStr = new String("");
    changeString(myStr);
}

main返回时,该值仍为""而不是"Hello world"。那是为什么?

另外,我该如何使它工作?假设我希望我的函数changeString将其得到的字符串更改为“Hello world”。

6 个答案:

答案 0 :(得分:34)

每个人都解释了为什么它不起作用,但没有人解释如何使其发挥作用。最简单的选择是使用:

String changeString() {
    return "Hello world";
}

main() {

    String myStr = new String("");
    myStr = changeString();
}

虽然方法名称在这里用词不当。如果您使用原始想法,则需要以下内容:

void changeString(ChangeableString str) {
    str.changeTo("Hello world");
}

main() {

    ChangeableString myStr = new ChangeableString("");
    changeString(myStr);
}

您的ChangeableString课程可能是这样的:

class ChangeableString {
    String str;

    public ChangeableString(String str) {
        this.str = str;
    }

    public void changeTo(String newStr) {
        str = newStr;
    }

    public String toString() {
        return str;
    }
}

关于参考文献的快速教训:

在Java方法中,所有内容都按值传递。这包括参考。这可以通过以下两种不同的方法来说明:

void doNothing(Thing obj) {
    obj = new Something();
}

void doSomething(Thing obj) {
    obj.changeMe();
}

如果您从doNothing(obj)(或任何地方)致电main(),则obj将不会在被叫方中更改,因为doNothing会创建新的Thing并在方法范围中指定对obj 的新引用。

另一方面,在doSomething中,您正在调用obj.changeMe(),并取消引用obj - 按值传递 - 并更改它。

答案 1 :(得分:7)

Java使用call by value策略来评估呼叫。

也就是说,该值会复制到str,因此如果您指定的str不会更改原始值。

答案 2 :(得分:3)

如果经常更改String,您还可以为变量分配StringBufferStringBuilder并更改其内容,并仅将其转换为String如果需要的话。

答案 3 :(得分:3)

NullUserException's excellent answer上扩展一下,这是一个更通用的解决方案:

public class Changeable<T> {
   T value;

   public Changeable(T value) {
      this.value = value;
   }

   public String toString() {
      return value.toString();
   }

   public boolean equals(Object other) {
      if (other instanceof Changeable) {
         return value.equals(((Changeable)other).value);
      } else {
         return value.equals(other);
      }
   }

   public int hashCode() {
      return value.hashCode();
   }
}

然后可以将Yura的原始代码重写为:

void changeString(Changeable<String> str){
   str.value = "Hello world":
}

void main() {
   Changeable<String> myStr = new Changeable<String>("");
   changeString(myStr);
}

而且,只是为了好玩,这里是Scala

class Changeable[T](var self: T) extends Proxy;

object Application {
   def changeString(str: Changeable[String]): Unit = {
      str.self = "Hello world";
   }

   def main(): Unit = {
      val myStr = new Changeable("");
      changeString(myStr);
   }
}

答案 4 :(得分:1)

因为引用myStr通过值传递给函数changeString,并且更改未反映回调用函数。

P.S:我不是Java人。

答案 5 :(得分:0)

比尔,我有一个问题的解决方案,它使用List作为java中的指针!

void changeString(List<String> strPointer ){
    String str = "Hello world";
    strPointer.add(0, str);
}

main(){
    LinkedList<String> list = new LinkedList<String>();
    String myStr = new String("");
    changeString(list);
    myStr = list.get(0);
    System.out.println( myStr );
}

这个答案需要一些额外的工作来插入和从列表中取出字符串,但是最后一行将打印“Hello world!”

我希望这也可以帮助别人!

-Port Forward Podcast