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

查看:130
本文介绍了如何以编程方式编译和实例化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类?

您需要先编译它。这可以通过 <$ c $以编程方式完成。 c> javax.tools API 。这只需要在本地计算机上安装 JDK JRE。

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

否则你需要涉及 Reflection API

这说的与实际问题无关:

That said and unrelated to the actual problem:

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天全站免登陆