java动态编译

背景自动生成代码的一个小工具中要通过创建一个Service.java源文件,然后对该源文件进行编译生成对应的class文件,之后通过反射调用Service.java的所有声明方法。自动生成的代码的功能是对每个Service.java的方法进行对应的case和data的自动生成。

步骤:

  1. 拷贝java文件:将子模块中的Service.java拷贝到common包的代码生成目录
  2. 编译java文件:通过动态编译工具进行文件编译
  3. 反射调用:调用Service.class的getDecalaredMethods()方法
  4. 生成data、case文件:
动态编译代码:
    public static void compile(String sourceFilePath, String classPath) throws IOException {
        //编译java文件
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
        Iterable sourcefiles = fileManager.getJavaFileObjects(sourceFilePath);
        //指定编译文件存放位置,如果不指定的话,编译的文件会和java源文件在一个文件夹中
        //这样的话加载类的时候会报java.lang.ClassNotFoundException
        Iterable<String> options = Arrays.asList("-d", classPath);
        compiler.getTask(null, fileManager, null, options, null, sourcefiles).call();
        fileManager.close();
    }

拷贝文件代码:
private static void generateServiceInterface(String sourceServicePath) throws IOException {

        File file = new File(sourceServicePath);
        String absoluteUtilServicePath = getAbsoluteUtilServicePath();
        File targetServiceFile = new File(absoluteUtilServicePath);
        targetServiceFile.delete();
        String packageLine = "package codeGenerator;";
        String oldPackageLine = "package";
        if (targetServiceFile.exists()) {
            targetServiceFile.delete();
        }
        Files.touch(targetServiceFile);

        List<String> strings = Files.readLines(file, Charsets.UTF_8);
        StringBuilder sourceCode = new StringBuilder();

        for (String string : strings) {
            if (string.contains(oldPackageLine)) {
                string = packageLine;
            }
            sourceCode.append(string);
            sourceCode.append(lineSeparator);
        }

        FileWriter fileWriter = new FileWriter(targetServiceFile);
        PrintWriter printWriter = new PrintWriter(fileWriter);
        printWriter.write(sourceCode.toString());
        printWriter.close();

        CompilerAPI.compile(absoluteUtilServicePath, classPath);
    }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java 提供了动态编译的功能,可以在程序运行时动态编译 Java 代码。动态编译需要使用 Java Compiler API,该 API 可以编译字符串形式的 Java 代码,生成对应的 class 文件。下面是一个简单的示例: ```java import javax.tools.*; import java.io.*; import java.util.*; public class DynamicCompilation { public static void main(String[] args) throws Exception { // 定义需要编译Java 代码 String code = "public class HelloWorld {\n" + " public static void main(String[] args) {\n" + " System.out.println(\"Hello, world!\");\n" + " }\n" + "}"; // 获取 Java 编译JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); // 定义编译任务 JavaFileObject file = new JavaSourceFromString("HelloWorld", code); Iterable<? extends JavaFileObject> compilationUnits = Arrays.asList(file); // 定义编译参数 List<String> options = new ArrayList<>(); options.addAll(Arrays.asList("-classpath", System.getProperty("java.class.path"))); // 执行编译任务 DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>(); StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null); JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, diagnostics, options, null, compilationUnits); boolean success = task.call(); // 输出编译结果 for (Diagnostic<? extends JavaFileObject> diagnostic : diagnostics.getDiagnostics()) { System.out.println(diagnostic.getMessage(null)); } fileManager.close(); if (success) { // 加载编译生成的 class 文件 Class<?> clazz = Class.forName("HelloWorld"); // 执行 class 的 main 方法 clazz.getDeclaredMethod("main", String[].class).invoke(null, (Object)args); } } // 定义一个 JavaFileObject 的实现类,用于编译 Java 代码 static class JavaSourceFromString extends SimpleJavaFileObject { private final String code; JavaSourceFromString(String name, String code) { super(URI.create("string:///" + name.replace('.', '/') + Kind.SOURCE.extension), Kind.SOURCE); this.code = code; } @Override public CharSequence getCharContent(boolean ignoreEncodingErrors) { return code; } } } ``` 上面的代码定义了一个需要编译Java 代码,并使用 Java Compiler API 编译生成了对应的 class 文件。你可以根据自己的需求修改代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值