Object Flashcards
The Object Class
The mother of all classes (quite literally!)
⚫ Not just a placeholder… Provides core functionality
⚫ Any class defined without an explicit superclass implicitly extends Object. Every single Java class therefore has Object as a superclass.
⚫ Any methods and instance variables defined in Object are therefore present in all classes…
⚫ Override them to provide useful tailored behaviour in your classes.
⚫ Examples include:
toString()
equals()
clone()
finalize()
hashCode()
Concurrency primitives (wait/notify) – See SCC211
toString()
Returns a humanly readable serialization of the object instance.
The format and content of the returned String is totally unconstrained by Java, is application specific, and left to the programmer.
Normally, a textual representation of the key instance variables held within the instance is provided.
Default behaviour: A textual representation of the unique ID used within the Java Virtual Machine to identify this object instance…
…not very useful for application programmers or end users!
equals()
Tests if the instance the method is called on and that provided as aparameter are, by the programmers definition, equivalent.
Remember all instances are referred to by Object References in Java.
So, if we have two different instances of a class, but their instance variables
have the same value, are they the same? The answer is subjective…
Default behaviour: reference equality. As tested by the “==“ operation. Two object instances are considered equal if and only if they reside at the same place in memory.
Equality and Equivalence 1
Reference equality has positive benefits, in that this guarantees uniqueness. However, there are many different types of equivalence
relationship…
Equivalence relations are implemented in Java using standard methods.
The equals method provides this functionality. Programmers can use
method overriding to create an equals method for their classes that implements their ‘preferred’ equivalence definition for that class:
Equality and Equivalence 2
finalize()
e that timing is non-deterministic –GC does not necessarily happen at
the same time as an object becomes eligible for garbage collection…
Default behaviour: No operation
Finalize() is deprecated in the Java API since 9.0
⚫ Notoriously difficult to implement safely, and no real need for it….
⚫ So don’t use it! ☺
hashcode()
Provides a hash value for the object
As used by the Collections API (HashMap and HashSet)
Objects that are equal() must return the same hashcode.
Hashcodes should be as distinct as possible, but not all objects are required
to have a unique hashcode.
Default behaviour: returns the memory address for the object as used by the underlying implementation of the Java Virtual Machine.
Always override the hashcode() method if you override equals()
clone() 1
Creates and returns a duplicate copy of the current object
instance.
A new instance is created, and a reference to that new instance is returned
The new instance is of the same type as the original, and has the same value
clone() 2
Clone and Equality… By contract, the new instance is created such that:
p == p.clone() false
p.equals(p.clone()) true or false !!
▪ However, cloning is not necessarily transient…
▪ What if an object being cloned refers to another object?
The Blue Pill or the Red Pill
We have a choice…
Do we clone just the first object instance, and simply take a duplicate of any
object references contained therein?
The story ends – you believe what you want to believe…
Or do we also clone any object instances the first object is referencing?
You see how deep the rabbit hole goes…
The Blue Pill: Shallow Copy
Duplicate only the first object
⚫ Primitive values are duplicated as values.
⚫ Object references are duplicated as values.
⚫ Relatively lightweight process
⚫ Preserves identity and semantics of any referenced instances
⚫ Default Behaviour: The clone() method in Object implements a shallow copy
The Red Pill: Deep Copy
Duplicate all references to objects
⚫ Primitive values are duplicated as values.
⚫ Object references are cloned.
⚫ Potentially expensive process, as number of object being cloned is unbounded!
⚫ Totally decouples cloned instance from the original, but can affect semantics
⚫ Risk of infinite cloning, if references are circular! (e.g. if bestMate is symmetric!)
implementing clone()
The clone() is by default disabled on new classes
⚫ Implement the Cloneable interface to allow your objects to be cloned:
⚫ n.b. This is purely permissive. Cloneable has no methods!
⚫ Shallow Copy: No other action is necessary
⚫ Deep Copy: Override the clone() method, and clone any (or all) of the object
references we are holding as instance variables.
Class Person implements Cloneable
Class Person implements Cloneable
{
public Object clone()
{
Person that = super.clone();
that.bestMate = that.bestMate.clone();
return that;
}
}
n.b. It is the programmer’s decision which (if any) related objects should
be cloned. This should be informed by your OO design… (c.f. SCC204!)