Rule 11: Don't compare classes by name
Sometimes you want to compare the classes of two objects to see whether they are the same; or you want to see whether an object has a particular class. When you do this, be aware that there can be multiple classes with the same name in a JVM. It is a mistake to compare classes by name since different classes can have the same name. A better method is to compare class objects for equality directly. For example, given two objects, A and B, if you want to see whether they are the same class, use this code:
if(a.getClass() == b.getClass()){
// objects have the same class
}else{
// objects have different classes
}
You should also be on the lookout for cases of less direct by-name
comparisons. Suppose, for example, you want to see whether an object
has the class "Foo." Here is the wrong way to do it:
if(obj.getClass().getName().equals("Foo")) // Wrong!
// objects class is named Foo
}else{
// object's class has some other name
}
Here's a better way to do it:
if(obj.getClass() == this.getClassLoader().loadClass("Foo")){
// object's class is equal to the class that this class calls "Foo"
}else{
// object's class is not equal to the class that
// this class calls "Foo"
}
Do note the legalistic comments in the last example. Whenever you use class names, you open yourself up to mix-and-match attacks, as described in Rule 7. You should also know that the Java language forces you to use class names all the time: in variable declarations, instanceof expressions, and exception-catching blocks. Only the designers of Java can prevent mix-and-match attacks, but you can avoid making the problem worse by avoiding by-name class comparisons.
No comments:
Post a Comment