Java 对象修改中的差异
我只是想知道是否有人能帮我解决这个问题:Java 对象修改中的差异,java,oop,mutability,Java,Oop,Mutability,我只是想知道是否有人能帮我解决这个问题: StringBuilder s=new StringBuilder("0123456789"); s.substring(1, 2); System.out.println(s); s.delete(2, 8); System.out.println(s); 第一个Sysout给出0123456789(尽管我希望有一个子字符串),但其他Sysout给出0189。我注意到一些Time和Date类也存在这种情况。我如
StringBuilder s=new StringBuilder("0123456789");
s.substring(1, 2);
System.out.println(s);
s.delete(2, 8);
System.out.println(s);
第一个Sysout给出0123456789(尽管我希望有一个子字符串),但其他Sysout给出0189。我注意到一些Time和Date类也存在这种情况。我如何确定什么形式将修改原始对象(在本例中为s)。这与对象的易变性有关吗?有什么一般规则吗?
提前谢谢
HKJavadoc告诉您一个方法是否修改它所操作的实例 返回一个新字符串,该字符串包含当前包含在此序列中的字符子序列。子字符串从指定的开始处开始,并延伸到索引末尾-1处的字符 删除此序列子字符串中的字符。子字符串从指定的开始处开始,并扩展到索引末尾-1处的字符,或者如果不存在这样的字符,则扩展到序列的末尾。如果“开始”等于“结束”,则不会进行任何更改 因此
子字符串
不会更改StringBuilder
的状态,而删除
会更改
用你自己的例子试试这个,希望它能澄清
StringBuilder s = new StringBuilder("0123456789");
String substring = s.substring(1, 2); // See here it returns a String, remember Strings are constants i.e. not mutable, not modifying the original StringBuilder s
System.out.println(substring);
StringBuilder delete = s.delete(2, 8); // see here it returns the String Builder, so remember StringBuilder is a mutable sequence of characters, hence modified the original
System.out.println(delete);
如果您在
AbstractStringBuilder
抽象类中看到substring
方法定义,该类后来被StringBuilder
类扩展,您将发现以下代码:
public String substring(int start, int end) {
if (start < 0)
throw new StringIndexOutOfBoundsException(start);
if (end > count)
throw new StringIndexOutOfBoundsException(end);
if (start > end)
throw new StringIndexOutOfBoundsException(end - start);
return new String(value, start, end - start);
}
AbstractStringBuilder
(StringBuilder
super类)中的delete定义为:
public AbstractStringBuilder删除(int开始,int结束){
如果(开始<0)
抛出新StringIndexOutOfBoundsException(开始);
如果(结束>计数)
结束=计数;
如果(开始>结束)
抛出新的StringIndexOutOfBoundsException();
int len=结束-开始;
如果(len>0){
System.arraycopy(值,开始+长度,值,开始,计数结束);
计数-=len;
}
归还这个;
}
从方法定义可以清楚地理解,它正在处理相同的
StringBuilder
对象内容,并且它不返回新对象,而是返回传递给它的相同对象引用。只有在方法“返回类型”无效时,才会修改当前对象。否则,将返回一个新对象。这些问题通常最好由用户回答。@SebVb不正确。delete
的返回类型不是void
。
@Override
public StringBuilder delete(int start, int end) {
super.delete(start, end);
return this;
}
public AbstractStringBuilder delete(int start, int end) {
if (start < 0)
throw new StringIndexOutOfBoundsException(start);
if (end > count)
end = count;
if (start > end)
throw new StringIndexOutOfBoundsException();
int len = end - start;
if (len > 0) {
System.arraycopy(value, start+len, value, start, count-end);
count -= len;
}
return this;
}