usar - para que sirve static en java
¿Cómo compilo y crea una instancia de una clase Java? (3)
¿Cómo cargo una clase de Java que no está compilada?
Necesitas compilarlo primero. Esto se puede hacer mediante programación con la API de javax.tools
. Esto solo requiere que el JDK se instale en la máquina local en la parte superior de JRE.
Aquí hay un ejemplo básico de patada de salida (dejando a un lado el manejo obvio de excepciones):
// Prepare source somehow.
String source = "package test; public class Test { static { System.out.println(/"hello/"); } public Test() { System.out.println(/"world/"); } }";
// Save source in .java file.
File root = new File("/java"); // On Windows running on C:/, this is C:/java.
File sourceFile = new File(root, "test/Test.java");
sourceFile.getParentFile().mkdirs();
Files.write(sourceFile.toPath(), source.getBytes(StandardCharsets.UTF_8));
// Compile source file.
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
compiler.run(null, null, null, sourceFile.getPath());
// Load and instantiate compiled class.
URLClassLoader classLoader = URLClassLoader.newInstance(new URL[] { root.toURI().toURL() });
Class<?> cls = Class.forName("test.Test", true, classLoader); // Should print "hello".
Object instance = cls.newInstance(); // Should print "world".
System.out.println(instance); // Should print "test.Test@hashcode".
Que cede como
hello
world
test.Test@ab853b
El uso adicional sería más fácil si esas clases implements
una cierta interfaz que ya está en el classpath.
SomeInterface instance = (SomeInterface) cls.newInstance();
De lo contrario, debe involucrar a Reflection API para acceder e invocar los métodos / campos (desconocidos).
Dicho esto y sin relación con el problema real:
properties.load(new FileInputStream(new File("ClassName.properties")));
Dejar que java.io.File
dependa del directorio de trabajo actual es una receta para problemas de portabilidad. No hagas eso. Coloque ese archivo en classpath y use ClassLoader#getResourceAsStream()
con una ruta de acceso relativa a la ClassLoader#getResourceAsStream()
.
properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("ClassName.properties"));
Esta pregunta ya tiene una respuesta aquí:
Tengo el nombre de clase almacenado en un archivo de propiedad. Sé que la tienda de clases implementará IDynamicLoad. ¿Cómo instalo la clase dinámicamente?
En este momento tengo
Properties foo = new Properties();
foo.load(new FileInputStream(new File("ClassName.properties")));
String class_name = foo.getProperty("class","DefaultClass");
//IDynamicLoad newClass = Class.forName(class_name).newInstance();
¿La nueva instancia solo carga archivos .class compilados? ¿Cómo cargo una clase de Java que no está compilada?
En la misma línea que la respuesta de BalusC, pero un contenedor un poco más automático está aquí en este fragmento de código de mi distribución kilim. https://github.com/kilim/kilim/blob/master/src/kilim/tools/Javac.java
Toma una lista de cadenas que contienen el código fuente de Java, extrae los nombres del paquete y de la clase pública / interfaz y crea la jerarquía del directorio / archivo correspondiente en un directorio tmp. A continuación, ejecuta el compilador de Java en él y devuelve una lista de nombres, pares de archivos de clases (la estructura ClassInfo).
Ayúdate del código. Está licenciado por MIT.
Su código comentado es correcto si sabe que la clase tiene un constructor público no-arg. Solo tiene que emitir el resultado, ya que el compilador no puede saber que la clase implementará IDynamicLoad
. Asi que:
IDynamicLoad newClass = (IDynamicLoad) Class.forName(class_name).newInstance();
Por supuesto, la clase tiene que ser compilada y en el classpath para que funcione.
Si está buscando compilar dinámicamente una clase a partir del código fuente, esa es una olla entera de peces.