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和存储在String“common pool”中的String(可以是interned)。在内部,他们的表现如何不同。它是如何改变子串算法的。 请在适当的地方引用书籍/文章/博客等。
答案 0 :(得分:21)
见评论:
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
注意:
致电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);
}
修改强>
什么是观点?
在Java 7u6之前,String基本上是char[]
,它包含带有偏移量和计数的字符串的字符(即字符串由count
字符组成,从{{1}开始位于offset
)。
调用substring时,会创建一个具有相同char[]
但不同偏移量/计数的新字符串,以有效地在原始字符串上创建视图。 (如上所述,当count = length和offset = 0时除外)。
从java 7u6开始,每次都会创建一个新的char[]
,因为字符串类中不再有char[]
或count
字段。
公共池的存储位置在哪里?
这是特定于实现的。在最近的版本中,池的位置实际上已移动。在更新的版本中,它存储在堆上。
游泳池是如何管理的?
主要特征:
offset
)new String("abc").intern();
被插入时(因为它是文字或因为S
被调用),如果存在intern()
,JVM将返回对池中字符串的引用。 1}}到equals
(因此S
应始终返回true)。答案 1 :(得分:2)
String
是不可变的对象。
String#subString
- 创建一个新的String。 Source
在代码中它是[open 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);
}