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:
false
true
false
true
有人可以解释的输出。 我知道字符串存储在堆和字符串存储在字符串“公共池”(可实习)之间的Java区分。 在内部,怎么会是他们的表现不同。 它是如何改变的子算法。 请引用书/文章/博客等酌情。
查看评论:
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,子返回一个新字符串,而不是在原来的串图(但不会使该例如差值)
当你调用特殊情况str1.substring(0,str1.length());
- 看到代码:
public String substring(int beginIndex, int endIndex) { //some exception checking then return ((beginIndex == 0) && (endIndex == value.length)) ? this : new String(value, beginIndex, subLen); }
编辑
什么是视图?
直到爪哇7u6,字符串基本上是一个char[]
包含与字符串的字符的偏移和计数(即,字符串是由count
的字符从起始offset
在位置char[]
当调用子,一个新的字符串与相同创建char[]
但不同的偏移/计数,有效地创建原始串图。 (除了当计数=长度和偏移量= 0如上所述)。
由于Java 7u6,一个新char[]
创建的每个时间,因为没有更多的count
或offset
在String类领域。
当存储在公共池到底是什么?
这是特定的实现。 池的位置在最近的版本实际上已经移动。 在最近的版本中,它被保存在堆上。
池是如何管理的?
主要特征:
- 字符串字面存储在池中
- (实习字符串存储池中
new String("abc").intern();
- 当一个字符串
S
被拘留(因为它是文字还是因为intern()
被调用),JVM将参考返回一个字符串池中是否有一个是equals
给S
(因此"abc" == "abc"
应该总是返回true)。 - 在游泳池的字符串可以被垃圾收集(这意味着一个实习字符串可能从池在某些阶段,如果它变得完全移除)
String
是不可变对象。
String#subString
-创建一个新的String。 资源
在代码是[开放JDK 6] -
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);
}
文章来源: How does Java store Strings and how does substring work internally? [closed]