Java中的String对象不是不可变的吗?

时间:2010-08-03 15:34:54

标签: java string immutability

String s = ...;

s = s.substring(1);

这可能吗?我以为你不能用Java改变String对象。

8 个答案:

答案 0 :(得分:23)

String对象是不可变的。但是,字符串引用是可变的。上面,s是参考。

答案 1 :(得分:5)

字符串对象是不可变的,这意味着s引用的实例的值不会改变。

您的代码不会改变实例 相反,它会更改s引用以引用新的字符串实例。

例如:

String a = "1";
String b = a;
a = "2";

执行此代码后,b仍为"1"b = a行设置b以引用"1"当前引用的同一a实例。
当您随后撰写a = "2"时,您正在更改a变量以引用其他("2")实例。
但是,"1"仍然引用的原始b实例未发生更改。

答案 2 :(得分:4)

是的,String个对象是不可变的。

变量s是对象的引用,引用本身可以指向它所指向的对象 - 重新分配引用不会影响它指向的对象。

String.substring方法实际上正在返回String的新实例,因此原始的String对象保持不变。

以下是一个简单的示例,表明原始String未被substring方法改变::

String s = "Hello!";
s.substring(1);

System.out.println(s);   // Prints "Hello!"

上面的例子将打印“你好!”因为substring方法将返回一个新的String而不是影响原始的String。原始String s = "Hello!"; s = s.substring(1); System.out.println(s); // Prints "ello!" 无法更改,因为它是不可变的。

将以上内容与以下内容进行比较:

s

在此示例中,对String的引用更改为substring方法返回的String,因此与s相关联的{{1}}是由`System.out.println'打印,输出的字符串将是“ello!”

答案 3 :(得分:2)

在这里,您要创建一个新字符串并将其分配给预先使用的引用。 s引用的原始字符串是垃圾回收。实际上没有任何字符串改变。

答案 4 :(得分:2)

//创建一个字符串“Hello”

的引用

String s =“Hello”;

//现在打印由s

引用的字符串的子串

<强>的System.out.println(s.subString(1));

//现在打印由s

引用的字符串

<强>的System.out.println(一个或多个);

以上代码段首先打印H ,然后在第二行,它将打印 Hello 现在为什么首先打印H ? :事物 subString()方法返回字符串 * 而不更改引用s *引用的字符串。 s仍指“你好”。现在,当您尝试打印s时,它将打印s所指的字符串。这样字符串“Hello”是不可移植的。你只能用它来产生另一个字符串,但你不能改变它。

当使用语句s = s.subString(1)时; 你正在做的是 s现在指的是“Hello”的subString(),但“Hello”本身仍未被修改。

答案 5 :(得分:0)

所以:

String foo = "foo";
foo.substring(1);
System.out.println(foo);

//of course..
foo = "aa";
System.out.println(foo);

答案 6 :(得分:0)

使用String s =“abc”时,创建对具有不可变值“abc”的String对象的String引用。

然后,当你说s = s.substring(1);时,你将s分配给一个新创建的包含“bc”的String对象 - 但是原始对象没有改变。

这是导致错误的常见原因,因为如果您未指定该值,则可能会出现意外结果。

许多新手Java开发人员将使用诸如trim()之类的方法,而不会意识到trim()不会影响String。

s.trim()&lt; - 什么都不做,返回一个修剪过的字符串 - 这是一个错误。

s = s.trim()&lt; - 存储修剪过的字符串 - 这是正确的。

答案 7 :(得分:0)

测试它:

String s = "Test";
String j = s;

s = s.substring(1);

s现在为Tj仍为Test