2

我想使用反射来获取一个新创建的java类的所有方法。如下所示,我通过从另一个文件复制创建了 java 类,然后使用 JavaCompiler 编译新创建的 Java。但我不知道为什么没有创建目标类文件。PS:如果我给错误的源目标java文件路径,会有编译信息像"javac: cannot find file: codeGenerator/Service.java". 谢谢你们。

private static Method[] createClassAndGetMethods(String sourceFilePath) throws IOException {
    File targetFile = new File("Service.java");
    File sourceFile = new File(sourceFilePath);
    Files.copy(sourceFile, targetFile);

    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    compiler.run(null, null, null, targetFile);
    Thread.sleep(5000);

    //After the Service.java compiled, use the class getDeclaredMethods() method.
    Method[] declaredMethods = Service.class.getDeclaredMethods();
    return declaredMethods;
}

编译方法:

        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        compiler.run(null, null, null, targetFile);
4

2 回答 2

1
Method[] declaredMethods = Service.class.getDeclaredMethods();

您不能编写直接依赖于Service.class除非Service已经编译的代码。您必须动态加载该类并从那里获取方法。目前很难看出包含此代码的类是如何加载的,而且它肯定不会给出正确的答案,除非在加载类时存在的版本Service.class,在这种情况下,您的代码将给出的方法那个版本,而不是新编译的版本。

您需要删除对整个源代码的所有引用,Service.class或者确实Service从整个源代码中删除,并ServiceClass.forName()编译后加载。执行干净的构建以确保Service.class部署中不存在任何文件。

于 2016-05-11T00:47:08.887 回答
0
public static void compile(String sourceFilePath, String classPath) throws IOException {
    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
    Iterable sourcefiles = fileManager.getJavaFileObjects(sourceFilePath);
    Iterable<String> options = Arrays.asList("-d", classPath);
    compiler.getTask(null, fileManager, null, options, null, sourcefiles).call();
    fileManager.close();
}

最后我以上述方式成功编译了目标Service.java。谢谢你们。

于 2016-05-11T07:52:35.447 回答