Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Class A is not equals Class A

We do have a cache (Map) with objects of Class TestClass. Another classloader initializes/loads TestClass at runtime again, so below code will threw a ClassCastException:

TestClass obj1 = (TestClass)map.get("key"); // throws a ClassCastException

ClassCastException when casting to the same class

Alright, I do understand this issue up to this point.

So, I was trying to find background information why is TestClass.class not equals TestClass.class. I assume that the different classloader set a different id to the ReferenceType? Anyone able to explain the background to me?

Best page I've found: http://www.objectsource.com/j2eechapters/Ch21-ClassLoaders_and_J2EE.htm

like image 637
Thomas Avatar asked Sep 13 '11 09:09

Thomas


Video Answer


2 Answers

Yes, your research points to the right direction: the same class definition loaded by different class loaders is seen as two distinct classes by the JVM. Thus casting between them fails with ClassCastException.

I think the difference is simply because there are two distinct class token objects in play. It has to be like this, since the classes loaded by the different loaders may in fact be different versions of the same class. It is known that the class token for every class is unique (within the same classloader realm, that is). It would open up a can of worms if the JVM started to compare class tokens by their various attributes, rather than by physical equality (==).

like image 80
Péter Török Avatar answered Oct 12 '22 17:10

Péter Török


What you experienced is the reason why custom class loaders exist. They allow to load different class with the same name in one JVM. The identity of a class in a JVM is given by the tuple consisting of the class name and the class loader. In the language Java a class is identified just by fully qualified name.

like image 40
jmg Avatar answered Oct 12 '22 16:10

jmg