Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/371.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.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 对象修改中的差异_Java_Oop_Mutability - Fatal编程技术网

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)。这与对象的易变性有关吗?有什么一般规则吗? 提前谢谢
HK

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

返回一个新字符串,该字符串包含当前包含在此序列中的字符子序列。子字符串从指定的开始处开始,并延伸到索引末尾-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;
}