如何加载未编译的Java类?
您需要先进行编译。可以使用javax.tools
API进行程序化操作。这仅需要在本地机器上安装JDK,并在JRE之上运行。
以下是一个基本的启动示例(忽略明显的异常处理):
String source = "package test; public class Test { static { System.out.println(\"hello\"); } public Test() { System.out.println(\"world\"); } }";
File root = Files.createTempDirectory("java").toFile();
File sourceFile = new File(root, "test/Test.java");
sourceFile.getParentFile().mkdirs();
Files.write(sourceFile.toPath(), source.getBytes(StandardCharsets.UTF_8));
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
compiler.run(null, null, null, sourceFile.getPath());
URLClassLoader classLoader = URLClassLoader.newInstance(new URL[] { root.toURI().toURL() });
Class<?> cls = Class.forName("test.Test", true, classLoader);
Object instance = cls.getDeclaredConstructor().newInstance();
System.out.println(instance);
产生的结果如下
hello
world
test.Test@cafebabe
如果这些类实现已经在类路径中的某个接口,那么进一步使用会更加容易。
SomeInterface instance = (SomeInterface) cls.getDeclaredConstructor().newInstance()
否则,您需要使用
反射 API来访问和调用(未知的)方法/字段。
话虽如此,与实际问题无关:
properties.load(new FileInputStream(new File("ClassName.properties")))
让
java.io.File
依赖于当前工作目录会导致可移植性问题。不要这样做。将该文件放在类路径中,并使用
ClassLoader#getResourceAsStream()
与类路径相关的路径。
properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("ClassName.properties"))