Java 堆行为中的新 String 和新 StringBuilder
Java new String and new StringBuilder in heap behavior
- 字符串池是否驻留在堆上?如果是,字符串文字是否符合垃圾回收条件?
使用new String("abc")
时,我们知道它在堆上创建一个对象,并将String字面量放入String池中。所以我的第二个问题是:
new StringBuilder("abc")
的行为方式是否与 new String("abc")
相同?如果是,StringBuilder如何操作String池中的String文字?
首先,是的,字符串池和它包含的字符串都在堆上。一旦字符串文字在字符串池中,它就永远不会从中删除。因此,在程序终止之前,字符串池中的所有字符串文字都是可访问的,因此不符合垃圾收集的条件。 (通过其他方式添加到字符串池的字符串可能符合垃圾回收条件。)
如果我们通过 new String("abc")
创建一个新的字符串对象,则会发生两件事:首先,由于字符串文字 "abc",将创建一个内容为 "abc" 的新字符串对象添加到字符串池(如果它不存在)。然后,由于 new String(...)
构造函数,创建了一个新的 String 对象,它是字符串文字的副本。这个新字符串没有放在字符串池中。因此,new String("abc") == "abc"
不成立。
代码 new StringBuilder("abc")
做的事情与 new String("abc")
不同,因为它创建的是 StringBuilder 对象而不是 String。但是,由于字符串文字 "abc",它确实确保内容为 "abc" 的字符串对象在字符串池中。
您混淆了编译时间、加载时间和运行时间。
在 class 加载时将字符串文字添加到常量池中。在 class 代码中的任何地方只需 提及 就足够了;您甚至不必执行 class.
中的任何代码行
另一方面,表达式 new String("literal")
每次被计算时都会产生一个新的 String
实例。该实例与常量池中的实例不同,并且具有字符串值的副本。
StringBuilder
在这方面与 String
的行为完全相同:它使用字符串文字值的副本进行初始化。
- 字符串池是否驻留在堆上?如果是,字符串文字是否符合垃圾回收条件?
使用new String("abc")
时,我们知道它在堆上创建一个对象,并将String字面量放入String池中。所以我的第二个问题是:
new StringBuilder("abc")
的行为方式是否与new String("abc")
相同?如果是,StringBuilder如何操作String池中的String文字?
首先,是的,字符串池和它包含的字符串都在堆上。一旦字符串文字在字符串池中,它就永远不会从中删除。因此,在程序终止之前,字符串池中的所有字符串文字都是可访问的,因此不符合垃圾收集的条件。 (通过其他方式添加到字符串池的字符串可能符合垃圾回收条件。)
如果我们通过 new String("abc")
创建一个新的字符串对象,则会发生两件事:首先,由于字符串文字 "abc",将创建一个内容为 "abc" 的新字符串对象添加到字符串池(如果它不存在)。然后,由于 new String(...)
构造函数,创建了一个新的 String 对象,它是字符串文字的副本。这个新字符串没有放在字符串池中。因此,new String("abc") == "abc"
不成立。
代码 new StringBuilder("abc")
做的事情与 new String("abc")
不同,因为它创建的是 StringBuilder 对象而不是 String。但是,由于字符串文字 "abc",它确实确保内容为 "abc" 的字符串对象在字符串池中。
您混淆了编译时间、加载时间和运行时间。
在 class 加载时将字符串文字添加到常量池中。在 class 代码中的任何地方只需 提及 就足够了;您甚至不必执行 class.
中的任何代码行 另一方面,表达式 new String("literal")
每次被计算时都会产生一个新的 String
实例。该实例与常量池中的实例不同,并且具有字符串值的副本。
StringBuilder
在这方面与 String
的行为完全相同:它使用字符串文字值的副本进行初始化。