如何以编程方式编译和实例化 Java 类? [英] How do I programmatically compile and instantiate a Java class?

查看:23
本文介绍了如何以编程方式编译和实例化 Java 类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将类名存储在属性文件中.我知道类存储将实现 IDynamicLoad.如何动态实例化类?

I have the class name stored in a property file. I know that the classes store will implement IDynamicLoad. How do I instantiate the class dynamically?

现在我有

     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();

newInstance 是否只加载已编译的 .class 文件?如何加载未编译的 Java 类?

Does the newInstance only load compiled .class files? How do I load a Java Class that is not compiled?

推荐答案

如何加载未编译的 Java 类?

你需要先编译它.这可以通过 javax 以编程方式完成.tools API.这只需要在本地机器上安装 JDKJRE 的.

You need to compile it first. This can be done programmatically with the javax.tools API. This only requires the JDK being installed at the local machine on top of JRE.

这是一个基本的启动示例(将明显的异常处理放在一边):

Here's a basic kickoff example (leaving obvious exception handling aside):

// 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".

哪个收益像

hello
world
test.Test@ab853b

如果这些类实现某个已经在类路径中的接口,那么进一步使用会更容易.

Further use would be more easy if those classes implements a certain interface which is already in the classpath.

SomeInterface instance = (SomeInterface) cls.newInstance();

否则您需要使用 反射 API 来访问和调用(未知) 方法/字段.

Otherwise you need to involve the Reflection API to access and invoke the (unknown) methods/fields.

说的与实际问题无关:

properties.load(new FileInputStream(new File("ClassName.properties")));

java.io.File 依赖于当前工作目录会导致可移植性问题.不要那样做.将该文件放在类路径中并使用 ClassLoader#getResourceAsStream() 带有类路径相对路径.

Letting java.io.File rely on current working directory is recipe for portability trouble. Don't do that. Put that file in classpath and use ClassLoader#getResourceAsStream() with a classpath-relative path.

properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("ClassName.properties"));

这篇关于如何以编程方式编译和实例化 Java 类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆