Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do immutable types need copy constructors?

Say I have an immutable DecimalNumber class:

public final class DecimalNumber {

    public final String str;

    public DecimalNumber(String str) { this.str = str; }
    public DecimalNumber(DecimalNumber copy) { this(copy.str); }

    public boolean isZero() {...}

    public DecimalNumber add(DecimalNumber other) {...}

    ...

}

and I decide to implement add like this:

public DecimalNumber add(DecimalNumber other) {

    if (other.isZero())
        return /* the same object */

    ...

}

Should I return this (less memory use) or a copied object new DecimalNumber(this)?

I would think simply returning this should be fine but is there ever a benefit to or reason for creating a new object or is it ever preferred?

like image 997
Salem Avatar asked Jan 17 '17 08:01

Salem


2 Answers

If a class is immutable and final, then you can return this.

If it is not final, you cannot be sure that the this instance is really immutable. You might actually be dealing with a subclass which adds mutable state.

Note that a class is only really immutable if:

  • All its fields are final, even the private ones. (Because of the Java memory model allowing other threads to see unfinished/default values for non-final fields, a non-final field with only a getter does not suffice.)
  • All its fields are either of immutable classes themselves, or access to them is restricted so that you can be sure they will never be changed.

In your case these two conditions are met, since String is an immutable class. If you known that no subclasses of your class exist, then you can (in fact, should IMHO) return this. To make sure that no subclasses of your class can exist, you can make it final.

like image 145
Hoopje Avatar answered Sep 30 '22 18:09

Hoopje


why do you feel strange about returning this?

If you would return a new object you would not need the if in the first place, so returning new DecimalNumber(this) is no option at all!

like image 33
Timothy Truckle Avatar answered Sep 30 '22 17:09

Timothy Truckle