Java 函数中字符串值的变化

发布于 2024-09-15 02:14:33 字数 351 浏览 9 评论 0原文

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

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

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

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

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

I have this very awkward question...

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

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

When main returns, the value is still "" and not "Hello world". Why is that?

Also, how do I make it work? Let's say I want my function changeString to change the string it got to "Hello world".

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

暮凉 2024-09-22 02:14:33

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

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();
}

如果您从 main() (或任何与此相关的地方)调用 doNothing(obj)obj 不会在被调用者中更改,因为 doNothing 创建一个新的 Thing 并将该新引用分配给 obj 方法

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

Everyone explained why it doesn't work, but nobody explained how to make it work. Your easiest option is to use:

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

main() {

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

Although the method name is a misnomer here. If you were to use your original idea, you'd need something like:

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

main() {

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

Your ChangeableString class could be something like this:

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

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

    public String toString() {
        return str;
    }
}

A quick lesson on references:

In Java method everything is passed by value. This includes references. This can be illustrated by these two different methods:

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

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

If you call doNothing(obj) from main() (or anywhere for that matter), obj won't be changed in the callee because doNothing creates a new Thing and assigns that new reference to obj in the scope of the method.

On the other hand, in doSomething you are calling obj.changeMe(), and that dereferences obj - which was passed by value - and changes it.

短叹 2024-09-22 02:14:33

Java 使用按值调用策略来评估调用。

也就是说,该值被复制到 str,因此,如果您分配给 str,则不会更改原始值。

Java uses a call by value startegy for evaluating calls.

That is, the value is copied to str, so if you assign to str that doesn't change the original value.

橘虞初梦 2024-09-22 02:14:33

如果经常发生 String 的更改,您还可以将 StringBufferStringBuilder 分配给变量并更改其内容,然后仅将其转换为需要时使用 String

If the changing of your String happens very often you could also assign a StringBuffer or StringBuilder to your variable and change its contents and only convert it to a String when this is needed.

狂之美人 2024-09-22 02:14:33

扩展一下 NullUserException 的优秀答案,这是一个更通用的解决方案:

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);
   }
}

Expanding a bit on NullUserException's excellent answer, here's a more general solution:

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's original code can then be rewritten as:

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

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

And, just for fun, here it is in 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);
   }
}
把人绕傻吧 2024-09-22 02:14:33

因为引用 myStr 是按值传递给函数 changeString 的,并且更改不会反映回调用函数。

PS:我不是Java人。

Because the reference myStr is passed by value to the function changeString and the change is not reflected back to the calling function.

P.S : I am not a Java guy.

薄荷港 2024-09-22 02:14:33

Bill,我对你的问题有一个解决方案,它在 java 中使用 List 作为指针!

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!”

我希望这也能帮助其他人!

-端口转发播客

Bill, I have a solution to your problem which uses a List as a pointer in 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 );
}

This answer takes a little extra work to insert and get out the string from the list, however the final line will print "Hello world!"

I hope this can help others as well!

-Port Forward Podcast

天暗了我发光 2024-09-22 02:14:33

这是 StringBuffer/StringBuilder 为我工作的又一个解决方案。

static void changeValue(StringBuilder str){
    str.append("newValue");
}

main(){
    StringBuilder originalVal= new StringBuilder();
    changeValue(originalVal);
    System.out.println(originalVal.toString());
}

Here's the one more solution by StringBuffer/StringBuilder worked for me.

static void changeValue(StringBuilder str){
    str.append("newValue");
}

main(){
    StringBuilder originalVal= new StringBuilder();
    changeValue(originalVal);
    System.out.println(originalVal.toString());
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文