Java - 字符串和常量池

我在 java.lang.String 看到了以下成员:

private final char value[];

My question is

以下语句是否会将文字字符串的副本复制到上面提到的 char[] 中,而另一个文字字符串副本也存在于常量池中 .

String b1 = new String("abc");

如果是这样,那么恒定池意味着什么呢?或者我们应该阻止使用new()来创建带文字的String?


@Update

那么,根据答案,为什么 String 类里面需要一个 char value[] 变量,为什么不直接引用常量池中的单个副本呢?如果使用 new String("...") 创建一个字符串,如果池中不存在,则文字是否不会被置于常量池中?

根据我的想象,使用 new String() 的唯一好处是,它可能比查询常量池更快;或者常量池有大小限制,当大小不够时它会删除旧的常量值吗?但我不确定这是否有效 .


Conclusion

所以,根据答案, new String() 应该只由常量池维护者本身使用,我们程序员不会 .

回答(3)

3 years ago

您可以使用new,但使用String的“intern”方法指定它会有点棘手 . 像这样:

String a = "ABC";
String b = new String("ABC").intern();
System.out.println(a == b);

输出为true,如果没有“实习生”,那么它是来自常量池的副本 .

String a = "ABC";
String b = new String("ABC");
System.out.println(a == b);

输出是假的 . 如果你查看这个String构造函数的原型,它会显示:

/**
     * Initializes a newly created {@code String} object so that it represents
     * the same sequence of characters as the argument; in other words, the
     * newly created string is a copy of the argument string. Unless an
     * explicit copy of {@code original} is needed, use of this constructor is
     * unnecessary since Strings are immutable.
     *
     * @param  original
     *         A {@code String}
     */
    public String(String original) {
        this.value = original.value;
        this.hash = original.hash;
    }

3 years ago

后者是对的 . 使用 new() 从文字创建 String 实例绝对没有意义 .

3 years ago

java中的字符串与任何其他编程语言一样,是一系列字符 . 这更类似于处理该char序列的实用程序类 . 此char序列在以下变量中维护:

/** The value is used for character storage. */
private final char value[];

当您使用 new 关键字创建字符串时

String b1 = new String("abc");

然后将对象创建到 Heap Memory 中,当 Java Compiler 遇到任何String文字时,它会在常量池中创建一个Object

现在b1指向堆内存中的对象,并且因为字符串文字也在那里,所以在常量池中也创建了一个对象,没有人指向它

正如有效的Java第2版所述

String s = new String("neerajjain");  //DON'T DO THIS!

因为当只能通过1个对象完成工作时,您不必要地创建了2个对象 .

但在某些情况下你可以使用 new String("string") 你可以找到它们here