对象修改的差异
我只是想知道是否有人可以帮我解决这个问题:
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.我注意到也有一些时间和日期类。我怎么能弄明白,什么forms将修改原始对象(在这种情况下是s )。 这与物体的可变性有关吗? 有什么一般规则吗? 在此先感谢HK
如果您在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); }
从方法定义中可以看到它返回一个新的String
对象,该方法不适用于实际的StringBuilder
内容。 因此,它们不会改变StringBuilder
对象的内容,而是返回一个新的String
对象。
现在,如果你在StringBuilder
类中看到delete
方法定义,它是:
@Override public StringBuilder delete(int start, int end) { super.delete(start, end); return this; }
而AbstractStringBuilder
( StringBuilder
超类)中delete的定义是:
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; }
从方法定义可以清楚地理解,它正在处理相同的StringBuilder
对象内容,并且它不返回新对象,而是返回传递给它的相同对象引用。
Javadoc告诉您方法是否修改了它所操作的实例。
子
返回一个新String ,其中包含此序列中当前包含的字符的子序列。 子字符串从指定的开始处开始,并扩展到索引结束处的字符-1。
删除
删除此序列的子字符串中的字符 。 子字符串从指定的开始处开始并延伸到索引结束处的字符 – 1或如果不存在此类字符则延伸到序列的结尾。 如果start等于end,则不进行任何更改。
因此, substring
不会在delete
更改StringBuilder
的状态。
@Hauptman Koening
试试这个用你自己的例子,希望它会澄清
StringBuilder s = new StringBuilder("0123456789"); String substring = s.substring(1, 2); // See here it returns a String, remember Strings are constants ie 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);