Duplating Objects
- Java considers equal objects to be ones who point to the same address in memory.
- You can’t test objects for equality using
==
the same way you would for primitives; even if their properties where identical (class type, instance vars, etc.), they still wouldn’t evaluate to true. - Similarly, you can’t copy an object using
=
because all you are doing is copying a reference; you will end up with two objects pointing to the same thing. - If you make a copy constructor which takes its own type as a parameter and copies its instance variables using equality operators you are essentially doing the same thing; you will have two distinct objects sharing pointers to the same objects (shallow copy).
- The only way this would be fine is if the class is immutable.
Mutability
- In Java mutability is applicable to object instance.
- The word itself is derived from mutate.
Mutable
Mutable: liable to change.
- You can change an object (or objects within it)
- Others can too; you can’t rely on it being the same.
- Presents a problem with using the
clone
method.
Immutable
Immutable: unchanging over time or unable to be changed.
- Primitives are immutable.
- Strings are immutable.
Cloning and Copying
- Java doesn’t provide any way of automatically performing deep copies.
- In order to make deep copies you need to either implement the Cloneable interface (and write a suitable
clone()
) or provide a copy constructor. - Copying is the preferred method of the two.
Goals of Cloning
x.clone() != x
x.clone().getClass() == x.getClass()
x.clone().equals(x)
Clone()
Method & Cloneable Interface
- Returns of the calling object, copying field-by-field without calling an objects constructor (essentially a type of 1memcopy1).
- As-is can return a shallow copy.
- If the source object has any mutable objects, those too will need to be cloned as-well.
- This requires
clone()
to be overwritten.
- Every object inherits a method named
clone
from theObject
class. - Requires the source object (and every object which it may extends) to implement
Cloneable
interface.- Continues to call
super.clone()
recursively up the inheritance hierarchy. - Else throws
CloneNotSupportedException
.
- Continues to call
- Has the signature
protected Object clone()
; can be extended.- Recall that methods can be changed to more permissive access.
- Recall that the return type can be changed to the class being cloned as all classes descend from the class
Object
(covariant returns permissible after Java 5).
- Shouldn’t use with
Copy Constructors
- Copy constructors are intended to make a deep copy.
- If a class has a copy constructor, an overwritten clone method can be use that instead.