In Effective JAVA by Joshua Bloch, when I was reading about static factory methods , there was a statement as follows
The ability of static factory methods to return the same object from repeated invocations allows classes to maintain strict control over what instances exist at any time. Classes that do this are said to be instance-controlled. There are several reasons to write instance-controlled classes. Instance control allows a class to guarantee that it is a singleton (Item 3) or noninstantiable (Item 4). Also, it allows an immutable class (Item 15) to make the guarantee that no two equal instances exist: a.equals(b) if and only if a==b. If a class makes this guarantee, then its cli- ents can use the == operator instead of the equals(Object) method, which may result in improved performance. Enum types (Item 30) provide this guarantee.
To investigate how == operator brings in performance improvements , I got to look at String.java
I saw this snippet
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String) anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
By performance improvement what does he mean here ? how it brings performance improvement .
Does he mean to say the following
If every class can assure that a.equals(b) if and only if a==b , it means it brings in an indirect requirement that there cannot be objects referring to 2 different memory spaces and still hold the same data , which is memory wastage . If they hold same data they are one and the same object .That is they point to same memory location.
Am I right in this inference ?
If I am wrong can you guide me in understanding this ?
If every class can assure that a.equals(b) if and only if a==b , it means it brings in an indirect requirement that there cannot be objects referring to 2 different memory spaces and still hold the same data , which is memory wastage . If they hold same data they are one and the same object .That is they point to same memory location.
Yes, that is what the author is driving at.
If you can (for a given class, this won't be possible for all, in particular it cannot work for mutable classes) call ==
(which is single JVM opcode) instead of equals
(which is a dynamically dispatched method call), it saves (some) overhead.
It works this way for enum
s for example.
And even if someone called the equals
method (which would be good defensive programming practice, you don't want to get into the habit of using ==
for objects IMHO), that method could be implemented as a simple ==
(instead of having to look at potentially complex object state).
Incidentally, even for "normal" equals methods (such as String's), it is probably a good idea in their implementation to first check for object identity and then short-cut looking at object state (which is what String#equals does, as you have found out).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With