2011-09-13 18 views
5

Abbiamo una cache (Map) con oggetti di Classe TestClass. Un altro programma di caricamento classe inizializza/carichi TestClass in fase di esecuzione di nuovo, così in basso codice gettato un ClassCastException:Classe A non è uguale a Classe A

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

ClassCastException when casting to the same class

Va bene, capisco questo problema fino a questo punto.

Quindi, stavo cercando di trovare informazioni di base perché è TestClass.class non uguale a TestClass.class. Suppongo che il diverso classloader abbia impostato un id diverso da ReferenceType? Qualcuno in grado di spiegare lo sfondo per me?

migliore cosa ho trovato: http://www.objectsource.com/j2eechapters/Ch21-ClassLoaders_and_J2EE.htm

risposta

8

Sì, i vostri punti di ricerca per la giusta direzione: la stessa definizione di classe caricato da diversi caricatori di classi è visto come due classi distinte dalla JVM. Così il casting tra loro fallisce con ClassCastException.

Penso che la differenza sia semplicemente perché ci sono due oggetti token di classe distinti in gioco. Deve essere così, poiché le classi caricate dai diversi caricatori potrebbero in realtà essere versioni differenti della stessa classe. È noto che il token di classe per ogni classe è univoco (nello stesso ambito del classloader, ovvero). Si aprirà una lattina di worm se la JVM ha iniziato a confrontare i token di classe con i loro vari attributi, piuttosto che con l'uguaglianza fisica (==).

1

Ciò che si è verificato è il motivo per cui esistono caricatori di classe personalizzati. Consentono di caricare classi diverse con lo stesso nome in una JVM. L'identità di una classe in una JVM è data dalla tupla costituita dal nome della classe e dal caricatore di classi. Nel linguaggio Java una classe viene identificata solo da un nome completo.

1

Chiunque è in grado di spiegarmi lo sfondo?

Come già spiegato da Péter Török, sono considerati diversi quando caricati da diversi classloader. Lo sfondo è che un server di applicazioni dovrebbe essere in grado di supportare diverse versioni di un'applicazione, ad es. diverse versioni delle stesse librerie incluse nei tuoi ear-files.

1

Non c'è mistero. uguaglianza runtime dei tipi è definita nel linguaggio Java Specification come segue:.

"In fase di esecuzione, diversi tipi di riferimento con lo stesso nome binario possono essere caricati contemporaneamente da diversi caricatori di classi Questi tipi possono o non possono rappresentare la stessa dichiarazione di tipo Anche se due di questi tipi rappresentano la stessa dichiarazione di tipo, sono considerati distinti. "

JLS 4.3.4 - When reference types are the same. (2 ° paragrafo)