Java中字符串的不变性 [英] Immutability of Strings in Java

查看:114
本文介绍了Java中字符串的不变性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下示例。

String str = new String();

str  = "Hello";
System.out.println(str);  //Prints Hello

str = "Help!";
System.out.println(str);  //Prints Help!

现在,在Java中,String对象是不可变的。那么为什么对象 str 可以赋值帮助!。这与Java中字符串的不变性相矛盾吗?任何人都可以向我解释不变性的确切概念吗?

Now, in Java, String objects are immutable. Then how come the object str can be assigned value "Help!". Isn't this contradicting the immutability of strings in Java? Can anybody please explain me the exact concept of immutability?

编辑:

好的。我现在得到它,但只是一个后续问题。以下代码如何:

Ok. I am now getting it, but just one follow-up question. What about the following code:

String str = "Mississippi"; 
System.out.println(str); // prints Mississippi 

str = str.replace("i", "!"); 
System.out.println(str); // prints M!ss!ss!pp! 

这是否意味着再次创建了两个对象(Mississippi和M!ss!ss! pp!)和引用 str 指向 replace()方法后的另一个对象?

Does this mean that two objects are created again ("Mississippi" and "M!ss!ss!pp!") and the reference str points to a different object after replace() method?

推荐答案

str 不是对象,它是对象的引用。 Hello帮助!是两个不同的字符串对象。因此, str 指向一个字符串。您可以更改指向的内容,但不能更改指向的内容。

str is not an object, it's a reference to an object. "Hello" and "Help!" are two distinct String objects. Thus, str points to a string. You can change what it points to, but not that which it points at.

获取此代码,例如:

String s1 = "Hello";
String s2 = s1;
// s1 and s2 now point at the same string - "Hello"

现在,我们可以对 s1 做任何 1 ,这会影响 s2 的值。它们引用相同的对象 - 字符串Hello - 但该对象是不可变的,因此无法更改。

Now, there is nothing1 we could do to s1 that would affect the value of s2. They refer to the same object - the string "Hello" - but that object is immutable and thus cannot be altered.

如果我们这样做:

s1 = "Help!";
System.out.println(s2); // still prints "Hello"

这里我们看到变异对象和更改引用之间的区别。 s2 仍指向与我们最初设置 s1 指向的同一对象。将 s1 设置为帮助!仅更改引用,而 String 它最初引用的对象保持不变。

Here we see the difference between mutating an object, and changing a reference. s2 still points to the same object as we initially set s1 to point to. Setting s1 to "Help!" only changes the reference, while the String object it originally referred to remains unchanged.

如果字符串可变的,我们可以这样做:

If strings were mutable, we could do something like this:

String s1 = "Hello";
String s2 = s1;
s1.setCharAt(1, 'a'); // Fictional method that sets character at a given pos in string
System.out.println(s2); // Prints "Hallo"






编辑回应OP的编辑:

如果你看一下 String.replace(char,char)的源代码(在JDK安装目录的src.zip中也可用 - 专业提示是无论何时你想知道它是如何运作的,你都可以看到它的作用如下:

If you look at the source code for String.replace(char,char) (also available in src.zip in your JDK installation directory -- a pro tip is to look there whenever you wonder how something really works) you can see that what it does is the following:


  • 如果有一个或多个在当前字符串中出现 oldChar ,制作当前字符串的副本,其中所有出现的 oldChar 都替换为 newChar

  • 如果当前字符串中不存在 oldChar ,则返回当前字符串。

  • If there is one or more occurrences of oldChar in the current string, make a copy of the current string where all occurrences of oldChar are replaced with newChar.
  • If the oldChar is not present in the current string, return the current string.

是的,Mississippi.replace('i','!')创建一个新的 String object。同样,以下成立:

So yes, "Mississippi".replace('i', '!') creates a new String object. Again, the following holds:

String s1 = "Mississippi";
String s2 = s1;
s1 = s1.replace('i', '!');
System.out.println(s1); // Prints "M!ss!ss!pp!"
System.out.println(s2); // Prints "Mississippi"
System.out.println(s1 == s2); // Prints "false" as s1 and s2 are two different objects

你现在的作业是看如果您将 s1 = s1.replace('i','!'); 更改为 s1 = s1.replace(' Q','!'); :)

Your homework for now is to see what the above code does if you change s1 = s1.replace('i', '!'); to s1 = s1.replace('Q', '!'); :)

1 实际上, 可以改变字符串(以及其他不可变对象)。它需要反思并且非常非常危险,除非你真的对破坏程序感兴趣,否则永远不要使用它。

1 Actually, it is possible to mutate strings (and other immutable objects). It requires reflection and is very, very dangerous and should never ever be used unless you're actually interested in destroying the program.

这篇关于Java中字符串的不变性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆