首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在Java中通过引用传递字符串?

在Java中通过引用传递字符串?
EN

Stack Overflow用户
提问于 2009-08-13 08:25:55
回答 12查看 218.1K关注 0票数 179

我习惯于在C中执行以下操作

代码语言:javascript
复制
void main() {
    String zText = "";
    fillString(zText);
    printf(zText);
}

void fillString(String zText) {
    zText += "foo";
}

输出结果为:

代码语言:javascript
复制
foo

然而,在Java中,这似乎不起作用。我假设是因为String对象是复制的,而不是通过引用传递的。我认为字符串是对象,它们总是通过引用传递。

这里发生什么事情?

EN

回答 12

Stack Overflow用户

发布于 2009-08-13 08:32:24

发生的情况是通过值传递引用,即传递引用的副本。java中的任何东西都不是通过引用传递的,因为字符串是不可变的,所以赋值创建了一个新的字符串对象,引用的副本现在指向该对象。原始引用仍然指向空字符串。

这对于任何对象都是一样的,即在方法中将其设置为新值。下面的例子让事情变得更加明显,但是连接一个字符串实际上是一回事。

代码语言:javascript
复制
void foo( object o )
{
    o = new Object( );  // original reference still points to old value on the heap
}
票数 55
EN

Stack Overflow用户

发布于 2009-08-13 08:26:57

java.lang.String是不可变的。

我讨厌粘贴URL,但是如果你在java环境中,https://docs.oracle.com/javase/10/docs/api/java/lang/String.html对于你阅读和理解是必不可少的。

票数 18
EN

Stack Overflow用户

发布于 2009-08-13 08:43:12

Java中的所有参数都是通过值传递的。当您将String传递给函数时,传递的值是对String对象的引用,但是您不能修改该引用,并且底层的String对象是不可变的。

作业

代码语言:javascript
复制
zText += foo;

等同于:

代码语言:javascript
复制
zText = new String(zText + "foo");

也就是说,它(在本地)将参数zText重新分配为一个新的引用,该引用指向一个新的内存位置,其中是一个新的String,其中包含zText的原始内容,并附加了"foo"

原始对象不会被修改,并且main()方法的局部变量zText仍然指向原始(空)字符串。

代码语言:javascript
复制
class StringFiller {
  static void fillString(String zText) {
    zText += "foo";
    System.out.println("Local value: " + zText);
  }

  public static void main(String[] args) {
    String zText = "";
    System.out.println("Original value: " + zText);
    fillString(zText);
    System.out.println("Final value: " + zText);
  }
}

打印:

代码语言:javascript
复制
Original value:
Local value: foo
Final value:

如果你想修改这个字符串,你可以使用StringBuilder或者其他一些容器(一个数组或者一个AtomicReference或者一个自定义容器类)来提供一个额外级别的指针间接性。或者,只需返回新值并对其赋值:

代码语言:javascript
复制
class StringFiller2 {
  static String fillString(String zText) {
    zText += "foo";
    System.out.println("Local value: " + zText);
    return zText;
  }

  public static void main(String[] args) {
    String zText = "";
    System.out.println("Original value: " + zText);
    zText = fillString(zText);
    System.out.println("Final value: " + zText);
  }
}

打印:

代码语言:javascript
复制
Original value:
Local value: foo
Final value: foo

在一般情况下,这可能是最类似于Java的解决方案--请参阅有效的Java项目“偏好不变性”。

正如前面提到的,StringBuilder通常会给您带来更好的性能--如果您有很多附加操作要做,尤其是在循环中,那么可以使用StringBuilder

但是,如果可以的话,尝试传递不变的Strings而不是可变的StringBuilders --您的代码将更容易阅读和维护。考虑将参数设置为final,并将集成开发环境配置为在将方法参数重新赋值为新值时发出警告。

票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1270760

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档