So where does the object holding "Hello" go
对 "Hello" 的引用 str 被分配了新值,因此对值 "Hello" 的引用丢失了,但它仍然在池中,可用,垃圾收集器可能会收集它并将其从堆中删除,具体不知道,假设在未来的代码中你仍然使用“Hello”字符串
String againhello= "Hello" ;
然后在这种情况下,垃圾收集器不应该收集它,因为“Hello”字符串被创建并再次被使用,只分配了新的引用。
对象的可变性和不变性背后的概念是,任何两个对象如果具有相同的值,就应该具有相同的哈希码,并且对于equals方法应该返回true,这对于String对象也是如此,但是为了提高性能。
他们将 String 设置为不可变的,因为他们不希望堆中填充相同的值和数量的不同对象,例如,假设
String sre="Hello";
String str="Hello";
如果没有 String 的不变性,那么 heap 中就会有两个对象,但是这里只有一个对象,只有两个引用变量。
what is difference between String and StringBuilder class.
Java 5 中添加了 StringBuilder 类,并提供了与 StringBuffer 类似的功能(即.. mutable string ),其中在每次修改 string 时,现在都不会创建新对象 使用 StringBuilder 的好处是它比 StringBuffer 相对快,因为 StringBuffer 是同步的类而 StringBuilder 不是,因此如果您想在不关心线程安全的环境中使用 StringBuffer,请考虑使用 StringBuilder 以获得更好的性能。
默认情况下,所有Java 类都是可变的,即可以修改它们的实例的内容。但是不可变性提供的优势很少(http://download.oracle.com/javase/tutorial/essential/concurrency/immutable.html),这就是为什么通过将某些类标记为最终类来使其不可变的原因。有问题的类是 String 和 Wrapper 类,如果您从逻辑上考虑它们(任何不可变类),那么提供的链接中的描述将开始有意义。让我们分别解决这两个问题:
String class:
正如 Kathy Siera 和 Bert Bates 在 SCJP 第 433 页中提到的,随着应用程序的增长,程序的字符串文字中存在大量冗余是很常见的。因此,为了解决这个问题,Java 的设计者提出了字符串池的概念,它通过有效利用可用内存来提高性能。但是现在,正如您可能想象的那样,如果多个引用变量在不知情的情况下引用同一个字符串,那么如果它们中的任何一个都可以更改字符串的值,那就太糟糕了。因此,需要使这个 String 类不可变。
Wrapper classes:
制作包装类的目标之一是提供一种机制来处理具有为对象保留的活动的原语,例如添加到集合中,或从具有对象返回值的方法返回。如果您考虑一个集合,它通常会被多个线程访问。如果包装类不是可变的,它将面临并发修改的风险,从而导致不一致的状态。因此,为了避免冲突,包装类是不可变的。
因此,一般来说,每当您遇到不可变类时,考虑其实例以并发方式使用是合乎逻辑的。此外,如果您不希望修改对象内容(原因之一是并发访问),则使该类不可变。