如何以编程方式编译和实例化Java类?

如何以编程方式编译和实例化Java类?,java,reflection,dynamic-loading,Java,Reflection,Dynamic Loading,我将类名存储在属性文件中。我知道类存储将实现IDynamicLoad。如何动态实例化该类 现在我有 Properties foo = new Properties(); foo.load(new FileInputStream(new File("ClassName.properties"))); String class_name = foo.getProperty("class","DefaultClass"); //IDynamicLoad newClas

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

现在我有

     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类?

如果您知道该类有一个公共的无参数构造函数,那么您的注释代码是正确的。您只需强制转换结果,因为编译器无法知道该类实际上将实现
IDynamicLoad
。因此:

   IDynamicLoad newClass = (IDynamicLoad) Class.forName(class_name).newInstance();
当然,类必须被编译并在类路径上运行

如果你想从源代码中动态编译一个类,那就完全是另一回事了

如何加载未编译的Java类

你需要先编译它。这可以使用以编程方式完成。这只需要在JRE之上的本地计算机上安装

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

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

SomeInterface instance = (SomeInterface) cls.newInstance();
否则,您需要涉及访问和调用(未知)方法/字段


这与实际问题无关:

properties.load(new FileInputStream(new File("ClassName.properties")));
java.io.File
依赖于当前的工作目录会导致移植性问题。不要那样做。将该文件放在类路径中,并与类路径相对路径一起使用

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

与BalusC的答案相同,但在我的kilim发行版的这段代码中有一个更自动的包装器。

它获取包含Java源代码的字符串列表,提取包和公共类/接口名称,并在tmp目录中创建相应的目录/文件层次结构。然后在其上运行java编译器,并返回名称、类文件对(ClassInfo结构)的列表


请随意阅读代码。这是麻省理工学院授权的。

只是一个离题的问题。当我按照您的方式加载属性时,我得到一个null,但当我这样做时,我得到了属性Foo.class.getResourceAsStream()?你能帮我理解你的密码吗?谢谢。该属性文件显然与
Foo
类放在同一个包中。如上所述,您需要指定类路径相对路径,例如
com/example/filename.properties
。但是,如果您可以保证属性文件始终与
Foo
class位于同一个包中,那么
class\getResourceAsStream()
也可以。您只会错过在应用程序外部对propertiesfile进行外部化的功能,以便在不修改/重新打包应用程序的情况下对其进行修改。
Files.write(source、sourceFile、StandardCharsets.utf8)没有为我编译。我想您需要
文件.write(sourceFile.toPath(),source.getBytes())
。此外,您应该为根目录使用生成的、独立于系统的临时目录,例如,通过
File root=Files.createTemporaryDirectory(null).toFile()
@Raffi:我不小心使用了番石榴而不是Java NIO,我已经修复了答案,谢谢!如果编译失败会发生什么?您可以这样做,但需要使用JDK,而不是JRE。
properties.load(new FileInputStream(new File("ClassName.properties")));
properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("ClassName.properties"));