子字符串方法 -​​ 相等性测试失败

Substring method - Equality test fails

This question之前有人问过,但没有真正回答。

如果 substring 方法创建了一个新对象,而这个对象在池中 "interned",那么为什么 == return 为 false。这是我的代码:

public class StringTest {
    public static void main(String[] args) {
        String str1 = "The dog was happy";
        String str2 = "The hog was happy";
        System.out.println(str1.substring(5));// just to make sure
        System.out.println(str2.substring(5));

        if (str1.substring(5) == str2.substring(5)) {
            System.out.println("Equal using equality operator");
        } else {
            System.out.println("Not equal using equality operator");
        }

        if (str1.substring(5).equals(str2.substring(5))) {
            System.out.println("Equal using equals method");
        } else {
            System.out.println("Not equal using equals method");
        }

    }
}

输出为:1. og 很高兴 2. og 很高兴 3. 使用相等运算符不等于 4. 使用 equals 方法等于

P.S。这是子字符串方法源代码:

public String substring(int beginIndex, int endIndex) {
    if (beginIndex < 0) {
        throw new StringIndexOutOfBoundsException(beginIndex);
    }
    if (endIndex > count) {
        throw new StringIndexOutOfBoundsException(endIndex);
    }
    if (beginIndex > endIndex) {
        throw new StringIndexOutOfBoundsException(endIndex - beginIndex);
    }
    return ((beginIndex == 0) && (endIndex == count)) ? this :
        new String(offset + beginIndex, endIndex - beginIndex, value);
}

P.S。这个问题已被标记为已被多人提问和回答,但我在 Stack Overflow 上找不到一个实例,其中有人真正解释了为什么 substring(0) 的计算结果为真。

答案就在你的问题本身。

尝试执行以下操作:

String str1 = "The dog was happy";
 String str2 = "The dog was happy";
 if (str1 == str2) 
 {
    System.out.println("Equal using equality operator");
 } 
  else 
 {
      System.out.println("Not equal using equality operator");
 }

你会得到"Equal using equality operator"。原因是您已将 str1 和 str2 都声明为字符串文字,并且内部池的概念适用。

现在,当您根据字符串 class 定义执行 str1.substring(5) 时,它 returns 是一个对象,而不是文字。因此 == 给出了错误的结果。

字符串class子串方法:

return (beginIndex == 0) ? this : new String(value, beginIndex, subLen);

如果您希望 == 对子字符串起作用,请对您的子字符串使用 intern() 方法。

变化: if (str1.substring(5) == str2.substring(5))

if (str1.substring(5).intern() == str2.substring(5).intern())

一个很好的文档来理解字符串创建和池化的细节:https://www.journaldev.com/797/what-is-java-string-pool