String s = new String("12")string s = "12" 如何进行内存分配
chou403
/ Javabase
/ c:
/ u:
/ 4 min read
以下内存是如何进行分配的 String s = new String(“12”)string s = “12”
在 Java 中,内存分配和字符串处理涉及一些细微的差别,特别是当你通过不同的方式创建字符串对象时。让我们详细分析两种不同的字符串创建方式的内存分配过程:
String s = new String(“12”)
这种方式显式地创建一个新的 String 对象。
-
常量池查找:
- 首先,Java 编译器会在常量池中查找是否有值为 “12” 的字符串。
- 如果常量池中没有值为 “12” 的字符串,则在编译时会在常量池中添加该字符串。
-
堆内存分配:
- 然后,在运行时,会使用 new 关键字在堆内存中创建一个新的 String 对象。
- 这个新的 String 对象会引用常量池中的 “12”。
代码的内存分配流程如下:
- 常量池中已有或添加了一个 “12” 字符串对象。
- 堆内存中创建一个新的 String 对象,该对象引用常量池中的 “12”。
String s = “12”
这种方式是直接使用字符串字面量。
-
常量池查找:
- 编译器会在常量池中查找是否有值为 “12” 的字符串。
- 如果常量池中没有值为 “12” 的字符串,则在编译时会在常量池中添加该字符串。
-
引用常量池:
- 运行时,变量 s 会直接引用常量池中的 “12”。
代码的内存分配流程如下:
- 常量池中已有或添加了一个 “12” 字符串对象。
- 变量 s 引用常量池中的这个字符串对象。
对比分析
- 内存消耗:
- String s = new String(“12”); 会在堆内存中创建一个新的 String 对象,这个对象会引用常量池中的 “12”,因此总共会有两个 String 对象(一个在常量池中,一个在堆中)。
- String s = “12”; 只会使用常量池中的字符串对象,因此只有一个 String 对象。
- 性能:
- String s = new String(“12”); 创建新的对象会比直接使用常量池中的对象稍慢,因为它涉及堆内存分配。
- String s = “12”; 更高效,因为它直接引用常量池中的对象,没有额外的对象创建开销。
代码示例
public class StringExample {
public static void main(String[] args) {
// 方式 1: 在堆中创建一个新的字符串对象
String s1 = new String("12");
// 方式 2: 直接引用常量池中的字符串对象
String s2 = "12";
// 比较引用
System.out.println(s1 == s2); // 输出 false,因为 s1 和 s2 引用不同的对象
System.out.println(s1.equals(s2)); // 输出 true,因为 s1 和 s2 的内容相同
}
}
在这个例子中,s1 和 s2 内容相同,但它们引用不同的对象,因为 s1 是一个新的 String 对象,而 s2 是常量池中的对象。
总结来说
- 使用 new String(“12”) 会在堆内存中创建一个新的对象,同时常量池中也会有一个 “12” 字符串对象。
- 使用 String s = “12”; 只会在常量池中有一个 “12” 字符串对象。