当前位置: 首页 > 面试题库 >

Java中字符串的不变性

龚振濂
2023-03-14
问题内容

考虑以下示例。

String str = new String();

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

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

现在,在Java中,String对象是不可变的。然后如何为对象str分配值“帮助!”。这是否与Java中字符串的不变性相矛盾?有人可以向我解释不变性的确切概念吗?

编辑:

好。我现在明白了,但只是一个后续问题。那么下面的代码呢:

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

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

这是否意味着将再次创建两个对象(“密西西比”和“ M!ss!ss!pp!”),并且引用strreplace()方法之后指向另一个对象?


问题答案:

str不是对象,而是对对象的引用。"Hello""Help!"是两个不同的String对象。因此,str指向一个字符串。你可以更改其指向的内容,但不能更改其指向的内容。

以下面的代码为例:

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

现在,没有什么1,我们可以做些什么来s1会影响价值s2。它们引用同一个对象-字符串"Hello"-但该对象是不可变的,因此无法更改。

如果我们做这样的事情:

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

在这里,我们看到了改变对象和更改参考之间的区别。s2仍然指向与最初设置的对象相同的对象s1。设置s1"Help!"仅更改引用,而String最初引用的对象保持不变。

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

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中找到它-一个专业技巧是在你想知道某事真正起作用时去那里查看),你会看到它确实是以下内容:

  • 如果oldChar当前字符串中有一个或多个出现,请复制当前字符串的副本,其中所有出现的oldChar都替换为newChar
  • 如果oldChar当前字符串中不存在,则返回当前字符串。
    是的,"Mississippi".replace('i', '!')创建一个新String对象。同样,以下内容成立:
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', '!');时的作用。

1实际上,它是可能的突变的字符串(和其他不可变的对象)。它需要反射,非常非常危险,除非你真的有兴趣破坏程序,否则永远不要使用它。



 类似资料:
  • 本文向大家介绍Java中的不可变字符串,包括了Java中的不可变字符串的使用技巧和注意事项,需要的朋友参考一下 在Java中,不可变对象是指那些不能更改或修改(一旦修改)数据的对象。字符串类是不可变的,即一旦我们创建了一个字符串对象,就无法修改其数据。

  • 据我所知, 可变字符串可以更改,不可变字符串不能更改。 这里我想这样改变字符串的值, 另一种方法是, 在这两种情况下,我都试图改变str的值。谁能告诉我,这两种情况的区别是什么,让我清楚地了解可变和不可变对象。

  • 问题内容: 有人告诉我不能更改Java中的字符串。下面的代码呢? 它不改变字符串吗?另外,replace()的实现在哪里;相比于(); 等于(); 提供?我只是在这里使用这些功能,但实际上在哪里实现? 问题答案: String.replace()返回一个新的String。 “名称”是对String对象的引用,因此可以将其重新分配为指向name.replace(),但它将指向一个新对象。 这是Str

  • 问题内容: 我们都知道这String在Java 中是不可变的,但是请检查以下代码: 为什么该程序会这样运行?为何值和改变了,但没有改变? 问题答案: 是不可变的*,但这仅意味着你无法使用其公共API对其进行更改。 你在这里所做的是使用反射来绕过常规API。同样,你可以更改枚举的值,更改整数自动装箱中使用的查找表等。 现在,原因s1和s2变化值是它们都引用相同的实习字符串。编译器执行此操作(如其他答

  • 问题内容: 我知道问题的标题不是很清楚,对此感到抱歉,不知道如何提出。我有一个非常基本的Java实现问题,我想着重于应用程序性能,但是它也涉及Java中的String创建模式。 我了解Java中字符串的不变性概念。我不确定的是,我在某处读到以下内容不会创建两个不同的String对象: 我想知道Java是怎么做到的?它实际上是否在程序存储器中寻找一个String值并检查其是否存在,如果不存在则创建一

  • 问题内容: 上面的代码片段中的代码产生以下输出。 a =’Hello’和b =’Hello’的长度分别为6和6,equals()为false 虽然两者的价值,并在控制台上显示的是,回报。怎么样? 问题答案: 和是 不是 可打印字符。它们都是控制字符,它们决定了文本应如何呈现-从左到右或从右到左。 您不会在终端中看到它们,并且它们不应该是等效的字符串。