1

我正在尝试编辑一个类文件并使其在运行时可供 JVM 使用。这可能吗,我该怎么做?

例如:

main() {
    for (int i=0;i<10;i++) {
        NewClass.method();
        //ask user if to continue..
    }
}

public class NewClass() {
    static void method() {
        sysout("hi");
    }
}

执行此循环时,我想更改文件 NewClass() 并将其加载到 JVM 中,以便打印“再见”。

这是完整的代码:

try {
    for (int iCount = 0; iCount < 10; iCount++) {
        BufferedReader br = new BufferedReader(new InputStreamReader(
                System.in));
        System.out.print("Enter which method:");
        int i = Integer.parseInt(br.readLine());
        System.out.println(i);
        if (i == 1) {
            Called.calledMethod1();
        } else {
            Called.calledMethod2();
        }
    }
} catch (NumberFormatException nfe) {
    System.err.println("Invalid Format!");
}

我想运行一个类的主要方法,当它运行时我想引用另一个类,编辑它,然后引用第二个类的相同方法并获得不同的输出。

不想

  1. 停止jvm
  2. 编辑代码
  3. 再次运行代码。

我想要

  1. 在运行时编辑代码,并立即反映更改。
4

1 回答 1

2

您必须使用 Java 反射。使用反射,

  1. 您可以在运行时使用Class forName 方法动态加载一个类。
  2. 在你得到的类实例上使用调用方法,你可以调用任何你想给它命名的静态方法。

如果您的课程在设计时是固定的,您只需保留第一点。一些代码:

...

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Enter which class:");
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
className=br.readLine()
int results = compiler.run(null, null, null, className+".java");
if(results == 0){

    Class clazz = Class.forName(className+".class");
    System.out.print("Compiled successfully.Enter which method:");
    Object returnValue=clazz.getMethod(br.readLine()).invoke(null);
}
...

但要注意安全问题:上面的代码让任何人都可以执行在运行时可访问的每个类的每个静态方法。如果安全性是您关心的问题之一,最好先验证从控制台接收到的输入并测试它们是否与您希望通过控制台提供的类方法之一匹配。

编辑

阅读您的评论后,我更好地理解了您的问题。如果你的目标是 Java 6,为了在运行时编译一个类,你可以使用Java Compiler object。我已经编辑了代码以包含 JavaCompiler 的使用。

于 2012-05-26T19:36:18.273 回答