Search code examples
javaoopmutability

Differences in Object modifications


i was just wondering if anybody could help me out with this :

    StringBuilder s=new StringBuilder("0123456789");
    s.substring(1, 2);
    System.out.println(s);
    s.delete(2, 8);
    System.out.println(s);

the first Sysout gives 0123456789(although i expected a substring) but other Sysout gives 0189. I have noticed that also with some Time and Date classes.How can i figure out, when what form is going to modify original object (in this case s). Is this related to Mutability of objects? Is there any general rule? Thanks in advance HK


Solution

  • If you see the substring method definition in AbstractStringBuilder abstract class which later extended by StringBuilder class, you will find below code:

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

    From the method definition you can see that it is returning a new String object, the method is not working on actual StringBuilder content. So their will no change in the content of StringBuilder object but rather a new String object will be returned.

    Now if you see delete method definition inside StringBuilder class it is:

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

    And the definition of delete in AbstractStringBuilder (StringBuilder super class) is :

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

    From the method definition it could be clearly understood that it is working on same StringBuilder object content and it is not returning a new object but rather the same object reference which is passed to it.