Implement clone () for immutable classes

I am developing a class library.

  • I have an abstract base class matrix for matrices that provides an implementation of some basic methods.
  • Matrix derivatives are specific subclasses for different types of matrices.
  • I have a requirement that matrices be clonable, so Matrix implements the Cloneable interface.
  • Some of the classes derived from the matrix are immutable.

It would be acceptable for the clone methods of immutable classes that instead of returning a clone of an object, the object itself is returned?

Some (simplified) codes for clarification:

abstract class Matrix implements Cloneable { ... } class ImmutableMatrix extends Matrix { ImmutableMatrix clone() { return this; } ... } class SomeOtherMatrix extends Matrix { SomeOtherMatrix clone() { SomeOtherMatrix other = super.clone(); ... return other; } ... } 
+6
source share
5 answers

I would have thought that calling super.clone() would be enough.

If your class is immutable, it should have cloned any mutable classes when it was created. Therefore, I would have thought it would be safe to have small copies of any fields in your class.

JavaDocs states that x.clone() != x is preferred. Although this is not an absolute requirement, your plan will certainly be violated by your plan to simply return this .

+8
source

Just return this to the clone () implementation of immutable classes.

+4
source

Although you could have immutable classes, just implementing clone to return references to yourself, I really don't see much value when using clone for things that may or may not be mutable, while there is no way to create mutable deals with immutable things and vice versa .

I would think that it would be better for your Matrix base class to include the IsImmutable and IsWritable , as well as the AsImmutable , AsMutable and AsNewMutable ; it should also include methods for reading and writing the matrix (although calling the "write" method on an unwritable matrix should throw an exception).

Define the static methods CreateImmutableMatrix and CreateMutableMatrix , which, under the Matrix condition, will create a new immutable or mutable matrix that is pre-initialized with the appropriate data.

Variable classes must implement AsImmutable to go to CreateImmutableMatrix , AsMutable to return itself, and AsNewMutable to go to CreateMutableMatrix .

Immutable classes must implement AsImmutable to return themselves, AsMutable to call AsNewMutable and AsNewMutable to go to CreateMutableMatrix .

Read-only shells must implement AsImmutable to call AsImmutable for wrapped objects, and AsMutable and AsNewMutable to call AsNewMutable for wrapped objects.

An object that receives a matrix, which it may or may not copy or mutate, can simply store it in a field (for example, Foo ). If he needs to mutate the matrix, it can replace Foo with Foo.AsMutable() . If the object containing the matrix needs to be copied, this field should be replaced in the copy using Foo.AsImmutable() or Foo.AsNewMutable() , depending on whether the field in the copy is likely to be mutated.

+2
source

Your class is not strictly immutable because it is not final: there may be mutable subclasses.

If someone wants to subclass ImmutableMatrix , he will not be able to implement clone() by calling super.clone() if you just return this . Therefore, in this case you should call super.clone() .

However, if you make your class final, I see no reason why not just return this .

0
source

Yes If we see the String (Immutable Class) behavior if the contents of the same object are returned, so I believe that you are correct, the clone () method should only return this.

-1
source

All Articles