Wiki Markup |
---|
In a JVM a class is identified by its fully- qualified class name AND_and_ its classloader. A class with the same name but different package name is different, and a class with the same fully- qualified name but which has been loaded with a different classloader is also different. "Two classes are the _same class_ (and therefore the _same type_) if they are loaded by the same class loader and they have the same fully qualified name" \[JVMSpec 99 §2§2.8.1\]. |
You may frequently want to know whether a given object has a specific class, or whether 2 two objects have the same class, for example, in implementing the equals()
method. If the comparison is performed incorrectly, your code might assume that 2 two objects are of the same class when they're not.
...
Conversely, a source of error is assuming that the same codebase will result in the same class in a JVM. While it is usually true in common user applications, it is not the case with J2EE servers like servlet containers, which could use different instances of classloaders to be able to deploy and undeploy applications at runtime without restarting the JVM. In this situation, 2 two objects whose classes come from the same codebase could be different classes to the JVM, and it could be confusing to get false from the equals()
method on their respective classes.
...
Noncompliant Code Example
In this non-compliant solutionnoncompliant example, the code compares the name of the class of object h
to the string "DefaultAuthenticationHandler
", and proceeds according to whether this comparison succeeds or not.
Code Block | ||
---|---|---|
| ||
  // determine whether object h has required/expected class name if (h.getClass().getName().equals("com.example.application.auth.DefaultAuthenticationHandler")) {      // code assumes it's an authorized class } |
...
In this compliant solution, we compare the class object of h
itself to the class object of the class that the current class loader would load with our required name.
Code Block | ||
---|---|---|
| ||
  // determine whether object h has required/expected class name if (h.getClass() == this.getClassLoader().loadClass("com.example.application.auth.DefaultAuthenticationHandler")) {      // code determines authorized class loaded by same classloader } |
The call to loadClass()
returns the class having the specified name in the current namespace (of the classloader), and the comparison is correctly performed on two class objects.
...
Noncompliant Code Example
This code compares the names of the 2 two classes of objects x
and y
and behaves accordingly.
Code Block | ||
---|---|---|
| ||
  // determine whether objects x and y have same class name if (x.getClass().getName().equals( y.getClass().getName() )) {      // code assumes objects have same class } |
...
This compliant solution correctly compares the 2 two objects' classes.
Code Block | ||
---|---|---|
| ||
  // determine whether objects x and y have same class if (x.getClass() == y.getClass()) {      // code determines objects have same class } |
...
Wiki Markup \[[JVMSpec 99|AA. Java References#JVMSpec 99]\] [§2§2.8.1 Class Names|http://java.sun.com/docs/books/jvms/second_edition/html/Concepts.doc.html]
Wiki Markup \[[Christudas 05|AA. Java References#Christudas 05]\]
Wiki Markup \[[Mcgraw 98|AA. Java References#Mcgraw 98]\]
Wiki Markup \[[Wheeler 03|AA. Java References#Wheeler 03]\] [Java|http://www.dwheeler.com/secure-programs/Secure-Programs-HOWTO/java.html]
...