【发布时间】:2013-02-18 08:59:16
【问题描述】:
我了解不可变对象是无法修改的对象。但是当我们使用函数时,可以修改字符串。那么我们如何说字符串是不可变的呢?这是一个提问的采访。需要尽快答复
【问题讨论】:
-
类似的帖子在这里 - stackoverflow.com/questions/1552301/…
标签: string immutability
我了解不可变对象是无法修改的对象。但是当我们使用函数时,可以修改字符串。那么我们如何说字符串是不可变的呢?这是一个提问的采访。需要尽快答复
【问题讨论】:
标签: string immutability
但是在我们使用函数的时候可以修改字符串。
不,你得到的是一个不同的字符串。示例:
String a, b, c;
a = "testing 1 2 3";
b = a.substring(0, 7); // Creates new string for `b`, does NOT modify `a`
c = a.substring(8);
System.out.println(b); // "testing"
System.out.println(c); // "1 2 3", proves that `a` was not modified when we created `b`
如您所见,"testing 1 2 3" 字符串未被 substring 调用修改;相反,我们得到了一个 new 字符串,其中只有 "testing"。
String 对象在 Java 中是不可变的,因为它们不提供修改现有 String 对象状态的方法。它们仅提供基于现有内容创建新 String 对象的方法。
(当然,除非你用反射玩非常顽皮的游戏。)
【讨论】:
a = a + " something";中,used指向的字符串a没有改变,但是创建了一个new字符串并且@ 987654330@ 更新为指向新字符串。任何引用旧字符串的内容都不受影响。试试String a, b; a = "one"; b = a; a = a + " two"; System.out.println(b);",你会看到之前的字符串没有改变,b 仍然指向它。
还有一件事是,当你创建一个字符串时,会在堆中为它分配一块内存,当你改变它的值时,会为那个字符串创建一个新的内存块,而旧的内存块变得符合条件用于垃圾收集,例如
String first = "xyz";
String second = "xyz";
second = "abc";
现在,当 first 被创建时,堆中的“first”会保留一块内存,而“second”则不会分配新空间,因为它们指向同一个东西,因此 second 指向堆中的相同空间,最后,当 second 的值改变时,它指向一个新的内存位置。因此字符串是不可变的,因为它的内容永远不会改变......它们被删除并分配新的内容...... 使用调试器并查看内存是如何被占用的......并注意原始数据类型的相同之处......内容改变而不是它们的内存位置......
希望对你有帮助!
【讨论】:
原因1.String是java中的对象。所以你不能随时改变..作为例子
String s= new String ("Md Omar Faroque");
s.concat("anik");
System.out.println(s);
输出将是:“Md Omar Faroque”。
这是为什么呢?当您添加“Anik”和“Md Omar Faroque”时,它变成了一个名为“Md Omar Faroque Anik”的新字符串。此新字符串未引用任何新变量。 S 仍然是“Md Omar Faroque”的参考变量。
再举个例子:
1. String s1 = "spring ";
2. String s2 = s1 + "summer ";
3. s1.concat("fall ");
4. s2.concat(s1);
5. s1 += "winter ";
6. System.out.println(s1 + " " + s2);
输出应该是“春冬春夏”
这是为什么呢?在第 5 行,s1 变成了一个新的字符串“spring winter”。它忘记了之前的值“spring”。由于 s1 现在引用了“春冬”,所以它已经打印出来了。
在第 2 行中,s2 引用了“春夏”。所以它虽然在第 2 行打印,但它再次与 s1 连接,并创建了新字符串“spring summer spring”。但是没有新变量引用这个值“spring summer spring”,仍然s2指向“spring summer”。
【讨论】:
public class Example{
public static void main(String[] args) {
String s = "hello";
String a = s;
if (a == s) {// it will print if part of statement
System.out.println("same reference");
} else {
System.out.println("not same reference");
}
s = "hi";// now we have change this 's'
if (a == s) { // if we have changed the same s reference the it should
// print same reference
System.out.println("same reference");
} else {
System.out.println("not same reference");// but it will printed
}
}
}
【讨论】: