"COMPUTER POWER TO THE PEOPLE! DOWN WITH CYBERCRUD!" - Theodor Nelson
My StuffLoveRespectAdmiration
My AmpsLinksArchives
|
Saturday, October 29, 2005Early Binding Gotchas
I recently ran into code like this:
Nothing really stands out as being WRONG, does it? It's making clever use of overridden methods and it looks like it might even save us some time if we know the object ahead of time (equals(MyType)). And that is where the "gotcha" is! Let's look at a test shall we?
OK, let's break this down shall we? The first test binds to equals(MyType) because the java compiler early binds its arguments in message sends. It figures out the argument types from the variable types used and finds the appropriate message to call at run-time (basically, it early binds the arguments and late binds the receiver). The second test binds to equals(Object) because it finds the most generic method it can. Since, we didn't say what type of null to use, the compiler picked Object for us. Next up, the third test binds just like the first, since we know the types of arguments. The fourth test is now trivial to us, right? Which leads us to the final and most troublesome test. Bascially, equals(MyType) got bound because the compiler doesn't know that we left that good ole null in there! So, where we thought we were safe, we are not. We just bypassed all our null checking code. Oh poo... So, what can you do?
The simple answer is to move your null check into your equals(MyType) method and be done with it. Just remember that null and early binding are gotchas not to be taken lightly when using overridden methods. |
Comments
Have you looked at Jakarta Commons EqualsBuilder? The JavaDocs describes this as typical usage:
public boolean equals(Object obj) {
if (obj instanceof MyClass == false) {
return false;
}
if (this == obj) {
return true;
}
MyClass rhs = (MyClass) obj;
return new EqualsBuilder()
.appendSuper(super.equals(obj))
.append(field1, rhs.field1)
.append(field2, rhs.field2)
.append(field3, rhs.field3)
.isEquals();
}
By Jeff, at 10:25 PM
That should be a link to http://jakarta.apache.org/commons/lang/api/org/apache/commons/lang/builder/EqualsBuilder.html
By Jeff, at 10:27 PM