Considera lo siguiente:
Map<Class<?>, Object> myMap = new HashMap<Class<?>, Object>();
Foo fooObject = New Foo();
myMap.put(fooObject.getClass(), fooObject)
Tenga en cuenta que java.lang.Class no implementa el método hashCode () en sí, sino que hereda de java.lang.Object implícita. He verificado esto en JDK 1.8.
Es java.lang.Class
seguro de usar como clave para una java.util.HashMap
? Será myMap.get(Foo.class)
siempre volver a los valores que puse como myMap.put(fooObject.getClass(), fooObject)
? Considere el software para tener varios cargadores de clases y mecanismos de serialización. ¿Seguirá siendo el mismo resultado? Si no es así ... ¿Cuál sería una alternativa?
Es seguro java.lang.Class utilizar como clave para una java.util.HashMap?
Si.
Voluntad myMap.get (Foo.class) siempre devuelven los valores que puse como myMap.put (fooObject.getClass (), fooObject)?
Si.
El uso de un Class
objeto como una llave en una HashMap
es seguro. La Class
clase hereda el Object::equals
y Object::hashCode
métodos. Por lo tanto equals
para Class
objetos está poniendo a prueba la identidad del objeto.
Esta es la semántica correcta para la igualdad tipo en Java. La aplicación de las ClassLoader::defineClass
asegura método que nunca se puede obtener dos diferentes Class
objetos que representan el mismo tipo Java.
Sin embargo, hay una arruga. La especificación del lenguaje Java ( JLS 4.3.4 ) establece lo siguiente:
En tiempo de ejecución, varios tipos de referencia con el mismo nombre binario pueden ser cargados simultáneamente por diferentes cargadores de clases. Estos tipos pueden o no representar la misma declaración de tipo. Incluso si dos de estos tipos representan la misma declaración de tipo, que se consideran diferentes.
(El nombre del archivo binario está relacionado con el nombre de dominio completo de un tipo llamado, y tiene en cuenta las clases anónimas, y los tipos de matriz.)
Lo que esto significa es que si (con éxito) de llamada ClassLoader::defineClass
para las clases con el mismo nombre totalmente calificado con dos cargadores de clases diferentes, obtendrá diferentes tipos de Java. Independientemente de los códigos de bytes que utilizó. Por otra parte, si se intenta molde de un tipo a otro, obtendrá una excepción de difusión clase.
Ahora la pregunta es qué este asunto en su caso de uso?
Respuesta: Probablemente no.
A menos que usted (o su marco) está haciendo las cosas difíciles con cargadores de clases, no se plantea la situación.
Si lo hace, entonces es probable que tenga los dos tipos (con el mismo nombre de dominio completo y cargadores de clases diferentes) para tener las diferentes entradas en el
HashMap
. (Debido a que los tipos son diferentes!)Pero si usted necesita los dos tipos de tener la misma entrada, entonces se puede usar el nombre completo de la clase como la clave, que se puede obtener utilizando
Class::getCanonicalName
. Si tiene que hacer frente a las clases de matriz, etc, a continuación, utilizarClass::getName
lo que devuelve el nombre del archivo binario para el tipo.
¿Qué pasa con los mecanismos de serialización?
Un Class
objeto no puede ser serializado usando serialización de objetos, ya que Class
no implementa Serializable
. Si implementa / utilizar algún otro mecanismo de serialización que es compatible con la serialización de Class
objetos, a continuación, que las necesidades mecanismo sea compatible con JLS 4.3.4.