2010-09-09 34 views
9

Probablemente pregunte, ¿por qué querría hacer eso ?, es porque estoy usando una clase (desde una biblioteca externa) que hace cosas en su inicializador estático y necesito saber si se ha hecho o no.¿Cómo comprobar si una clase está inicializada?

Miré ClassLoader, pero no encontré nada que pareciera útil. ¿Algunas ideas?

+1

quiere decir "si una clase está inicializada". hay una gran diferencia – irreputable

+0

Gracias por señalar eso. Cambié el título. – mik01aj

+1

¿Qué biblioteca? Tal vez haya un efecto secundario que podría verificar (por ejemplo, los controladores JDBC se registran en el DriverManager). –

Respuesta

13

Puede usar el método ClassLoader.findLoadedClass(). Si devuelve null, entonces la clase no está cargada. De esta forma, no carga la clase si no estaba cargada.


ADVERTENCIA: Este código no funciona muy bien aquí, en el sistema de cargador de clases, findLoadedClass() está protegido, es necesario anular con su propio cargador de clases.

Comprobar el siguiente enlace Sobre el mismo tema para comprobar si una clase se carga con el cargador de clases de sistema de

if(ClassLoader.getSystemClassLoader().findLoadedClass("java.lang.String") != null){ 
    System.out.println("Yepee, String is loaded !"); 
} 

Muy buen punto de @irreputable:

"cargado" no significa "inicializado". inicialización sólo ocurre en momentos puntuales definidos por JLS3 $ 12.4.1

y cito:

una clase o interfaz de tipo T se inicializará inmediatamente antes de la primera aparición de cualquiera de los siguientes :

  • T es una clase y una instancia de se crea T.
  • T es una clase y un método estático declarado por se invoca T.
  • Se asigna un campo estático declarado por T asignado.
  • Se utiliza un campo estático declarado por T y el campo no es una variable constante (§4.12.4).
  • T es una clase de nivel superior, y un comunicado assert(§14.10) anidado dentro de léxico T se ejecuta.

Invocación de ciertos métodos reflectantes en la clase Class y en paquete java.lang.reflect también causa clase o interfaz de inicialización. Una clase o interfaz no se inicializará bajo ninguna otra circunstancia.


Recursos:

Por sa Me tema:

+0

¿Esto no causará que se cargue 'String' cuando realiza la llamada al método, ya que tiene que evaluar el' String' literal '" java.lang.String "'? –

+0

Bueno, el código realmente no funciona en absoluto, no podemos llamar a findLoadedClass() en el cargador de clases predeterminado. Así que considera esto como un simple ejemplo. –

+0

Claro, un simple ejemplo artificial, pero, no obstante, ¿su afirmación 'if' siempre se evaluará como' verdadera'? –

4

¿Por qué no solo hace referencia a la clase (creando una referencia, creando una instancia o accediendo a un miembro estático)? Eso iniciará el inicializador de tipo si aún no se ha activado y, si lo tiene, aún está listo para continuar.

+0

Porque esta biblioteca lee parámetros con 'System.getProperty' y necesito saber si aún puedo cambiarlos o no. – mik01aj

2

Usted puede obtener la JVM para imprimir las clases, ya que los carga, utilizando el distintivo -verbose. Esto podría ser de ayuda para ti.

java -verbose Dummy|head 
[Opened C:\Program Files\Java\jre6\lib\rt.jar] 
[Loaded java.lang.Object from C:\Program Files\Java\jre6\lib\rt.jar] 
[Loaded java.io.Serializable from C:\Program Files\Java\jre6\lib\rt.jar] 
[Loaded java.lang.Comparable from C:\Program Files\Java\jre6\lib\rt.jar] 
[Loaded java.lang.CharSequence from C:\Program Files\Java\jre6\lib\rt.jar] 
[Loaded java.lang.String from C:\Program Files\Java\jre6\lib\rt.jar] 

(por cierto, acaba de intentar esto en un programa Hola Mundo y se cargaron 309 clases wow!)

1

Usted puede intentar algo como esto:

Clase c = new cargador de clases() { Clase c = findLoadedClass (className); }.do;

+0

no funciona, definitivamente devolverá nulo. – irreputable

0
Class.forName("com.abc.Xyz", true, this.getClass().getClassLoader()) 

Se bloqueará hasta que la clase se ha inicializado (por sí mismo o algún otro flujo)

0

Si no es demasiado tarde .. Esto debería funcionar bien, así

Class.forName().newInstance(); 

la newInstance() crea una nueva instancia de la clase representada por este objeto de Clase. La clase se instancia como si fuera una nueva expresión con una lista de argumentos vacía. La clase se inicializa si aún no se ha inicializado.

1

Sé que es muy tarde, pero creo que esta respuesta podría ser útil. Si no está demasiado asustado (y se le permite) para utilizar la clase sun.misc.Unsafe hay un método que precisamente hace eso: El método

sun.misc.Unsafe.shouldBeInitialized(Class) 

vuelve true si y sólo si el Class proporcionado como parámetro es (cargado pero) no inicializado.

Cuestiones relacionadas