对象修改的差异

时间:2017-01-02 08:14:04

标签: 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.我注意到还有一些时间和日期类。我怎么能弄明白,当什么形式要修改原始对象时(在这个案例s)。这与物体的可变性有关吗?有什么一般规则吗? 提前致谢 HK

3 个答案:

答案 0 :(得分:2)

Javadoc告诉您方法是否修改了它所操作的实例。

<强> substring

  

返回一个新的String ,其中包含此序列中当前包含的字符的子序列。子字符串从指定的开始处开始,并延伸到索引结束处的字符-1。

<强> delete

  

删除此序列的子字符串中的字符。子字符串从指定的开始处开始并延伸到索引结束处的字符 - 1或如果不存在此类字符则延伸到序列的结尾。如果start等于end,则不进行任何更改。

因此,substring StringBuilder不会改变delete的状态。

答案 1 :(得分:2)

@Hauptman Koening

尝试使用您自己的示例,希望它能澄清

    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);

答案 2 :(得分:2)

如果您在substring抽象类中看到AbstractStringBuilder方法定义,后来由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对象。

现在,如果您在delete类中看到StringBuilder方法定义,那么它就是:

@Override
public StringBuilder delete(int start, int end) {
    super.delete(start, end);
    return this;
}

AbstractStringBuilderStringBuilder超类)中删除的定义是:

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对象内容,并且它不会返回一个新对象,而是返回传递给它的相同对象引用。