Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/392.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java string类的subString()函数的工作原理_Java_String - Fatal编程技术网

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原则