Home
img of docs

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 对象。

  1. 常量池查找:

    • 首先,Java 编译器会在常量池中查找是否有值为 “12” 的字符串。
    • 如果常量池中没有值为 “12” 的字符串,则在编译时会在常量池中添加该字符串。
  2. 堆内存分配:

    • 然后,在运行时,会使用 new 关键字在堆内存中创建一个新的 String 对象。
    • 这个新的 String 对象会引用常量池中的 “12”。

    代码的内存分配流程如下:

    • 常量池中已有或添加了一个 “12” 字符串对象。
    • 堆内存中创建一个新的 String 对象,该对象引用常量池中的 “12”。

String s = “12”

这种方式是直接使用字符串字面量。

  1. 常量池查找:

    • 编译器会在常量池中查找是否有值为 “12” 的字符串。
    • 如果常量池中没有值为 “12” 的字符串,则在编译时会在常量池中添加该字符串。
  2. 引用常量池:

    • 运行时,变量 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” 字符串对象。