Estoy tratando de cargar un archivo java .class dinámicamente y llamarlo por reflexión.¿La carga de clase de Java es extremadamente lenta?
Tengo una clase llamada Foo; tiene un constructor vacío y tiene un método llamado doit() que toma un argumento de cadena y devuelve una cadena. También invierte la cadena.
Aquí está mi código:
URL url = new URL("file://C:/jtest/");
URLClassLoader loader = new URLClassLoader(new URL[]{url});
Class<?> cl = loader.loadClass("Foo");
Constructor<?> cons = cl.getConstructor((Class[])null);
Object ins = cons.newInstance(new Object[]{});
Method meth = cl.getDeclaredMethod("doit", String.class);
Object ret = meth.invoke(ins, new Object[]{"!dlroW olleH"});
System.out.println((String)ret);
Como era de esperar esta imagen Impresiones "Hello World!". Sin embargo, se necesitan aproximadamente 30 segundos para completar. Sé que la reflexión es lenta, pero espero que sea de 10 ms o algo así.
Estoy usando Eclipse con JRE 1.6.0_13, y yo estoy corriendo Windows Vista.
¿Qué estoy haciendo mal aquí?
Gracias.
Edit: He perfilado el código, y todo su tiempo se utiliza en la tercera línea (loadClass()). Todo lo demás sucede al instante.
Edité: He puesto el código en un bucle; la función lenta de alguna manera se optimiza y toma 30 segundos solo en el primer ciclo.
Editar: he encontrado la solución.
En lugar de:
URL url = new URL("file://C:/jtest/");
lo cambié a:
URL url = new URL("file:/C:/jtest/");
ahora funciona perfectamente. No sé por qué funciona, pero no veo cómo yo (y otras 5 personas) podría haberme perdido eso. Ahora me siento tonto ..
loadClass primero comprueba la caché para ver si la clase ya está cargada, si no recuerdo mal. Eso explicaría por qué no tarda mucho en la segunda iteración. –
¿El verdadero "Foo" está en un paquete? Cargando desde el paquete predeterminado (sin paquete) puede tener efectos extraños. Intenta moverte a foo.Foo. – flicken
Eso es interesante ... nueva URL ("archivo:/C:/jtest /"). GetPath() es/C:/jtest /. Me pregunto cómo lo interpreta URLClassLoader. –