2012-08-08 26 views
6

Mientras jugaba con cargadores de clase I tiene la siguiente excepción:ClassCastException debido a cargadores de clases?

Exception in thread "main" java.lang.ClassCastException: xxx.Singleton cannot be cast to xxx.Singleton 

¿Quiere decir esto que una instancia de un cargador de clases no se pueda convertir en una clase de otro cargador de clases?

Compruebe mi código donde puedo instanciar 3 singletons gracias a los cargadores de clase, incluso con la "" seguridad.

public static void main(String[] args) throws Exception { 
     URL basePath = new URL("file:/myMavenPath/target/classes/"); 

    Object instance = getClassInstance(Singleton.class); 
    System.out.println(instance); 
    // 
    Object instance2 = getClassInstance(
      new URLClassLoader(new URL[]{basePath} , null) 
        .loadClass("my.Singleton") 
    ); 
    System.out.println(instance2); 
    // 
    Object instance3 = getClassInstance(
      new URLClassLoader(new URL[]{basePath} , null) 
        .loadClass("my.Singleton") 
    ); 
    System.out.println(instance3); 

    // Only the 1st cast is ok 
    Singleton testCast1 = (Singleton) instance; 
    System.out.println("1st cast ok"); 
    Singleton testCast2 = (Singleton) instance2; 
    System.out.println("2nd cast ok"); 
    Singleton testCast3 = (Singleton) instance3; 
    System.out.println("3rd cast ok"); 
} 

private static Object getClassInstance(Class clazz) throws Exception { 
    Method method = clazz.getMethod("getInstance"); 
    method.setAccessible(true); 
    return method.invoke(null); 
} 


class Singleton { 

    private static final Singleton INSTANCE = new Singleton(); 

    public static Singleton getInstance() { 
     return INSTANCE; 
    } 

    private Singleton() { 
     Exception e = new Exception(); 
     StackTraceElement[] stackTrace = e.getStackTrace(); 
     if (!"<clinit>".equals(stackTrace[1].getMethodName())) { 
      throw new IllegalStateException("You shall not instanciate the Singleton twice !",e); 
     } 
    } 

    public void sayHello() { 
     System.out.println("Hello World ! " + this); 
    } 

} 

Respuesta

3

No se puede emitir entre cargadores de clases. La identidad de clase se compone de un nombre completamente calificado y del cargador de clases. Compruebe identidad de clase crysishere.

+1

¿Puede Java ejecutar identidad Cr ** y ** sis though? –

2

Sí, estás en lo cierto.

Esto sucede a menudo en los proyectos OSGi, debido a la mala gestión de la dependencia.

Cuestiones relacionadas