Java中的String对象是不可变的吗?
在这里,您正在创建一个新的字符串并将其分配给一个预先使用的参考。被引用的原始字符串是垃圾收集。实际上没有字符串改变
垃圾收集?? – 2013-07-30 09:29:31
字符串对象是不可变的,这意味着s
引用的实例的值不能更改。
您的代码不会改变实例。
相反,它将s
引用更改为引用新的字符串实例。
例如:
String a = "1";
String b = a;
a = "2";
执行该代码后,b
仍然"1"
。
行b = a
设置b
指的是a
当前所指的相同的"1"
实例。
当您随后编写a = "2"
时,您正在更改a
变量以引用不同的("2"
)实例。
但是,原来的"1"
实例,其中b
仍然指向,没有改变。
是的,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
被改变为由substring
方法返回的String
,所以当与s
相关联的String
由`系统打印。 out.println“,输出的字符串将是”ello!“
所以:
String foo = "foo";
foo.substring(1);
System.out.println(foo);
//of course..
foo = "aa";
System.out.println(foo);
当你用String s = ”ABC“,创建一个字符串引用具有不可变值的String对象 ”ABC“
然后,你的时候。比如s = s.substring(1);你将s赋值给新创建的包含“bc”的String对象 - 但原始对象不变赋值时,可能会得到意想不到的结果。
许多新手Java开发人员将使用像trim()这样的方法,但并未意识到trim()不会影响String。
s.trim()< - 什么也没有,返回一个修剪过的字符串 - 这是一个错误。
s = s.trim()< - 存储修剪过的字符串 - 这是正确的。
测试:
String s = "Test";
String j = s;
s = s.substring(1);
s
现在T
和j
仍然Test
。
//创建参考s到字符串 “Hello”
的String = “你好”;串的
//现在打印SUBSTRING由s称为
的System.out.println(s.subString(1));
//现在打印字符串由s称为
的System.out.println(一个或多个);
上面代码段会第一打印ħ,然后在第二线它将打印你好。 现在为什么首先打印H? :事情是subString()方法返回一个字符串 * 而不更改引用s *引用的字符串。 s仍然指“你好”。现在,当您尝试打印s时,它会打印s所指向的字符串。以这种方式字符串“你好”是不可变的。你只是能够使用它来产生另一个字符串,但你不能改变它。
当使用语句s = s.subString(1); 你在做什么是s现在引用了“Hello”的subString(),但是“Hello”本身仍然没有被修改。
如果只有's.substring(1)'会改变's'中的字符串,那么你应该是正确的。但是你正在为's'分配一个新的字符串。 – 2010-08-03 15:38:20
您只是更改引用s,而不是原始字符串本身。一个小样式点 - 创建一个新的,描述性命名的局部变量通常更好,而不是像这样重新使用变量。 – mikera 2010-08-03 15:41:00
不要将对象与引用混淆。对象可能是可变的或不可变的。参考文献可能是“最后”或不是。制作引用'final'不会使对象不可变。不可变的对象可以通过引用来引用,而不必是“final”。 – polygenelubricants 2010-08-03 15:54:54