Java如何存储字符串以及子字符串如何在内部工作? [英] How does Java store Strings and how does substring work internally?

查看:89
本文介绍了Java如何存储字符串以及子字符串如何在内部工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

class StringTesting {
    public static void main(String args[])
    {
        String str = "abcd";
        String str1 = new String("abcd");
        String str2 = str.substring(0,2);
        String str3 = str.substring(0,2);
        String str4 = str.substring(0,str.length());
        String str5 = str1.substring(0,2);
        String str6 = str1.substring(0,2);
        String str7 = str1.substring(0,str1.length());

        System.out.println(str2 == str3);
        System.out.println(str == str4);
        System.out.println(str5 == str6);
        System.out.println(str1 == str7);
    }
}

这是我在java 1.6.0_27上得到的输出:

Here is the output I get on java 1.6.0_27:

false
true
false
true

有人可以解释输出。我知道Java区分存储在堆中的String和存储在Stringcommon pool中的String(可以是interned)。在内部,他们的表现如何不同。它是如何改变子串算法的。
请在适当情况下引用书籍/文章/博客等。

Can someone please explain the output. I know Java differentiates between String stored in heap and String stored in String "common pool" (which can be interned). Internally, how is their representation different. How does it change the substring algorithm. Kindly cite book/article/blogs etc. wherever appropriate.

推荐答案

查看评论:

    String str = "abcd";  // new String LITERAL which is interned in the pool
    String str1 = new String("abcd"); // new String, not interned: str1 != str
    String str2 = str.substring(0,2); // new String which is a view on str
    String str3 = str.substring(0,2); // same: str3 != str2
    String str7 = str1.substring(0,str1.length()); // special case: str1 is returned

注意:


  • 从Java 7u6开始,substring返回一个新字符串而不是原始字符串上的视图(但这对该示例没有影响)

  • 调用 str1.substring(0,str1.length()); 时的特殊情况 - 请参阅代码:

  • Since Java 7u6, substring returns a new string instead of a view on the original string (but that does not make a difference for that example)
  • Special case when you call str1.substring(0,str1.length()); - see code:

public String substring(int beginIndex, int endIndex) {
    //some exception checking then
    return ((beginIndex == 0) && (endIndex == value.length)) ? this
            : new String(value, beginIndex, subLen);
}


编辑


什么是视图?

What is a view?

在Java 7u6之前,String基本上是一个 char [] ,它包含带有偏移量和计数的字符串的字符(即字符串由 count char [] 中的 offset 位置开始的字符)。

Until Java 7u6, a String is basically a char[] that contains the characters of the string with an offset and a count (i.e. the string is composed of count characters starting from the offset position in the char[]).

调用substring时,会创建一个新字符串,其中包含相同的 char [] ,但是不同的偏移量/ count,有效地创建原始字符串的视图。 (除非count = length和offset = 0,如上所述)。

When calling substring, a new string is created with the same char[] but a different offset / count, to effectively create a view on the original string. (Except when count = length and offset = 0 as explained above).

从java 7u6开始,新的 char [] ,因为字符串类中不再有 count offset 字段。

Since java 7u6, a new char[] is created every time, because there is no more count or offset field in the string class.


公共池的存储位置在哪里?

Where is the common pool stored exactly?

这是特定于实现的。在最近的版本中,池的位置实际上已移动。在更新的版本中,它存储在堆上。

This is implementation specific. The location of the pool has actually moved in recent versions. In more recent versions, it is stored on the heap.


如何管理池?

How is the pool managed?

主要特征:


  • 字符串文字存储在池中

  • Interned字符串存储在池中( new String(abc)。intern();

  • 当一个字符串 S 被实习(因为它是一个文字或因为 intern()被调用时),JVM将返回对池中字符串的引用,如果有一个字符串等于 S (因此abc==abc应该总是返回true。。

  • 池中的字符串可以被垃圾收集(意味着一个实习字符串可能如果它已满,可以在某个阶段从池中删除)

  • String literals are stored in the pool
  • Interned strings are stored in the pool (new String("abc").intern();)
  • When a string S is interned (because it is a literal or because intern() is called), the JVM will return a reference to a string in the pool if there is one that is equals to S (hence "abc" == "abc" should always return true).
  • Strings in the pool can be garbage collected (meaning that an interned string might be removed from the pool at some stage if it becomes full)

这篇关于Java如何存储字符串以及子字符串如何在内部工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆