Pregunta

I am developping a class library.

  1. I have an abstract base class Matrix for matrices that provides implementations for some of the basic methods.
  2. Derived from Matrix are concrete subclasses for different types of matrices.
  3. I have the requirement for matrices to be cloneable, so Matrix implements the Cloneable interface.
  4. Some of the classes derived from Matrix are immutable

Would it be acceptable for the immutable classes' clone methods that instead of returning a clone of the object, the object itself is returned?

Some (oversimplified) code 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;
    }
    ...
}
¿Fue útil?

Solución

I would have thought calling super.clone() would be sufficient.

If your class is immutable then it should have already cloned any mutable classes when it was constructed. Hence I would think it would be safe to have shallow copies of any fields your class has.

The JavaDocs state that x.clone() != x is preferred. While this isn't an absolute requirement, it would certainly be violated by your plan to just return this.

Otros consejos

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

While you could have the immutable classes simply implement clone to return references to themselves, I really don't see much value in using clone on things that may or may not be mutable, absent some way of making mutable copes of immutable things and vice versa.

I would think it would be better for your base Matrix class to include methods IsImmutable and IsWritable, along with AsImmutable, AsMutable, and AsNewMutable methods; it should also include methods to read and write the matrix (though calling the "write" method on non-writable matrix should throw an exception).

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

Mutable classes should implement AsImmutable to pass themselves to CreateImmutableMatrix, AsMutable to return themselves, and AsNewMutable to pass themselves to CreateMutableMatrix.

Immutable classes should implement AsImmutable to return themselves, AsMutable to call AsNewMutable, and AsNewMutable to pass themselves to CreateMutableMatrix.

Read-only wrappers should implement AsImmutable to call AsImmutable on the wrapped objects, and AsMutable and AsNewMutable to call AsNewMutable on the wrapped objects.

An object which receives a matrix which it may or may not need to copy or mutate may simply store it in a field (e.g. Foo). If it needs to mutate the matrix, it can replace Foo with Foo.AsMutable(). If the object containing the matrix needs to be copied, the field should be replaced in the copy with either Foo.AsImmutable() or Foo.AsNewMutable() depending upon whether the field in the copy will likely need to be mutated.

Your class is not strictly immutable since it is not final: there can 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. So in that case you should call super.clone().

However, if you make your class final, I don't see any reason why not just return this.

Yes If we see the behavior of String (Immutable class), If contents are same the same object is returned, so I thing your are right , clone() method should only return this.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top