关于字符串常量池

时间:2017-11-07 12:13:36

标签: java

假设我有2个字符串ImagePopupa="ABC",我相信只会创建一个字符串,这两个字符串引用都将指向字符串常量池中的实例。在这种情况下,为什么我们需要b="ABC"方法进行比较。请澄清。

3 个答案:

答案 0 :(得分:1)

  

我相信只会创建一个字符串,这两个字符串引用都将指向字符串常量池中的实例。

关闭。 "常数池"实际上是指类文件表示中的一个部分,它包含除字符串之外的其他内容。

您的" ABC"字符串对象在运行时保存,根据Java规范没有名称。 Javadoc只是将它称为"字符串池",而JLS根本没有明确提及它。此外,此池还可能包含由在运行时调用String::intern的应用程序代码创建的字符串。

  

为什么我们需要.equals()方法进行比较?

因为大多数字符串对象不是通过调用String::intern创建的。

只有由类加载器实例化的字符串对象(因为它们代表源代码中的文字)或调用String::intern的应用程序代码才会在池中。

如果你不知道(肯定)你正在比较的两个字符串已被实习,那么你不能确定==会给出正确的答案。因此,测试两个字符串是否相等的安全方法是使用String::equals

(脚注:G1垃圾收集器也可以做一些称为&#34;字符串重复数据删除&#34;(见JEP 192)但这是一个不同的实习过程,不会改变<字符串对象的em> identity 。因此与此问题无关。)

答案 1 :(得分:0)

对于容量有限的所有类型的池或缓存,这基本相同 - 不能假设池的内容是恒定的并且永远不会改变。

在任何地方都可能会创建大量其他字符串,并且在达到容量时,池可能会随意逐出项目。

其他组件可能仍会创建具有完全相同内容的新字符串(new String(byte [])),您无法控制并可能最终进行比较。

答案 2 :(得分:0)

来自java.lang.String#equals()的JDK8实现:

/**
 * Compares this string to the specified object.  The result is {@code
 * true} if and only if the argument is not {@code null} and is a {@code
 * String} object that represents the same sequence of characters as this
 * object.
 *
 * @param  anObject
 *         The object to compare this {@code String} against
 *
 * @return  {@code true} if the given object represents a {@code String}
 *          equivalent to this string, {@code false} otherwise
 *
 * @see  #compareTo(String)
 * @see  #equalsIgnoreCase(String)
 */
public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = value.length;
        if (n == anotherString.value.length) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            while (n-- != 0) {
                if (v1[i] != v2[i])
                    return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

请注意,实现首先检查thisanObject的身份。这是这种依赖于实现的优化的正确位置。您的代码不应该依赖于这样的假设,因为String#equals()会为您执行此操作。