java - 为什么一个String不指向String池中的同一个对象?

标签 java string object heap-memory stack-memory

我知道字符串是不可变的。在下面的示例中,将在字符串池区域和s1中创建一个字符串常量对象。将指向"Hello" 。另外s2将创建一个具有相同值 "Hello" 的字符串常量。

但我不明白为什么s2不要指向第一个“Hello”。据我了解,字符串“Hello”已经存在于字符串池区域中,如果我使用该值创建另一个字符串,它将指向现有对象,而不是创建另一个对象。例如s3指向同一个对象,如 s1

我没有使用new关键字 s2 。为什么s2不像 s1 和 s3 一样指向同一个对象?

public class DemoApp {

    public static void main(String args[]) {

        String s1 = "Hello";
        String s2 = "Hello friends".substring(0, 5);
        String s3 = "Hello";

        System.out.println(s2);        //Hello
        System.out.println(s1 == s2);  //false
        System.out.println(s1 == s3);  //true
    }
}

输出为:

Hello
false 
true

最佳答案

如果你查看 substring 方法的实现,你会发现它使用 new 运算符创建一个 String,因此返回的字符串不存在于字符串池中。

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

替换您的代码

String s2 = "Hello friends".substring(0, 5);

与 String s2 = " friend 们好".substring(0, 5).intern();

你会看到它返回true。

关于java - 为什么一个String不指向String池中的同一个对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49966870/

相关文章:

java - java中的ClassCastException

java - SWT 中的白色只读文本字段

C++ std::vector<std::string> 迭代器段错误

javascript - 如何将数组 [] 转换为一系列 { key : value } paired objects?

java - 没有空格的扫描仪输入字符串?

java - Spring 4 中没有合格的 bean 类型

java - 如何使用 Scala/Java 中的索引从另一个数组分配一个数组的元素?

c++ - 迭代/递归

Java 初学者 - 不带开关的罗马数字到十进制

Java 中类似 JavaScript 的对象数据类型?