Java string类的subString()函数的工作原理
请参阅以下代码Java string类的subString()函数的工作原理,java,string,Java,String,请参阅以下代码 String s = "Monday"; if(s.subString(0,3).equals("Mon"){} String s2 = new String(s.subString(0,3)); String s3 = s.subString(0,3); 我知道第2行仍然指向“Monday”,并且有一个偏移量和计数设置为0,3的新字符串对象 第4行将在字符串池中创建一个新字符串“Mon”,并指向它 但不确定第5行的行为是否与第2行或第4行类似 如果第2行或第4行的错误,
String s = "Monday";
if(s.subString(0,3).equals("Mon"){}
String s2 = new String(s.subString(0,3));
String s3 = s.subString(0,3);
我知道第2行仍然指向“Monday”,并且有一个偏移量和计数设置为0,3的新字符串对象
第4行将在字符串池中创建一个新字符串“Mon”,并指向它
但不确定第5行的行为是否与第2行或第4行类似
如果第2行或第4行的错误,也请更正。阅读此
“返回一个新字符串…”
读这个
“返回一个新字符串…”
正如Pete Kirkham所指出的,这是特定于实现的。我的答案仅适用于Sun JRE,并且仅适用于Java 7 update 6之前的版本。 关于正常的
子字符串
调用,您是对的,只需创建一个引用与原始字符串相同的字符数组的新字符串。第五行也是这样。新的字符串对象引用恰好被分配给变量,这一事实并不会改变方法的行为
为了清楚起见,您说在第2行中,新字符串仍然指向“Monday”-字符串中的字符数组引用将指向与“Monday”相同的字符数组。但是“星期一”本身是一个字符串,而不是一个字符数组。换句话说,在第2行完成时(忽略GC),有两个字符串对象,都引用相同的字符数组。一个数为6,另一个数为3;两者的偏移量均为0
不过,您对第4行使用“字符串池”的看法是错误的——那里没有池。但是,它与其他线路不同。调用String(String)
构造函数时,新字符串将获取原始字符串的字符数据副本,因此它是完全独立的。如果您只需要包含非常大的原始字符串的一小部分的字符串,这将非常有用;它允许在保留小部分的副本时对原始的大字符数组进行垃圾收集(假设没有其他需要)。在我自己的经验中,一个很好的例子就是从一行中读一行。默认情况下,BufferedLineReader
将使用80个字符的缓冲区读取行,因此返回的每个字符串将使用至少80个字符的字符数组。如果你读的是很多很短的行(单字),那么仅仅通过使用奇形怪状的单词,在内存消耗方面就会有所不同
line = new String(line);
这可能非常重要
这有帮助吗?正如Pete Kirkham所指出的,这是特定于实现的。我的答案仅适用于Sun JRE,并且仅适用于Java 7 update 6之前的版本。 关于正常的
子字符串
调用,您是对的,只需创建一个引用与原始字符串相同的字符数组的新字符串。第五行也是这样。新的字符串对象引用恰好被分配给变量,这一事实并不会改变方法的行为
为了清楚起见,您说在第2行中,新字符串仍然指向“Monday”-字符串中的字符数组引用将指向与“Monday”相同的字符数组。但是“星期一”本身是一个字符串,而不是一个字符数组。换句话说,在第2行完成时(忽略GC),有两个字符串对象,都引用相同的字符数组。一个数为6,另一个数为3;两者的偏移量均为0
不过,您对第4行使用“字符串池”的看法是错误的——那里没有池。但是,它与其他线路不同。调用String(String)
构造函数时,新字符串将获取原始字符串的字符数据副本,因此它是完全独立的。如果您只需要包含非常大的原始字符串的一小部分的字符串,这将非常有用;它允许在保留小部分的副本时对原始的大字符数组进行垃圾收集(假设没有其他需要)。在我自己的经验中,一个很好的例子就是从一行中读一行。默认情况下,BufferedLineReader
将使用80个字符的缓冲区读取行,因此返回的每个字符串将使用至少80个字符的字符数组。如果你读的是很多很短的行(单字),那么仅仅通过使用奇形怪状的单词,在内存消耗方面就会有所不同
line = new String(line);
这可能非常重要
这有帮助吗?在第5行-->s3=Mon。在第5行-->s3=Mon
我知道第2行仍然指向“Monday”,并且有一个偏移量和计数设置为0,3的新字符串对象
目前,Sun JRE实现也是如此。我似乎还记得,过去的Sun实现不是这样,JVM的其他实现也不是这样。不要依赖未指定的行为。GNU类路径可能会复制数组(我不记得用什么比率来决定何时进行复制,但如果副本比原始副本小得多,它就会进行复制,这将一个很好的O(N)算法变成了O(N^2))
第4行将在字符串池中创建一个新字符串“Mon”,并指向它
不,它会在堆中创建一个新的字符串对象,并遵循与任何其他对象相同的垃圾收集规则。它是否共享相同的基础字符数组取决于实现。不要依赖未指定的行为
建造师说:
初始化新创建的字符串对象,使其表示与参数相同的字符序列;换句话说,新创建的字符串是参数字符串的副本
建造师说:
分配新字符串,使其表示当前包含在字符数组参数中的字符序列。复制字符数组的内容;随后对字符数组的修改不会影响新创建的字符串
遵循良好的OO原则