首页 > 编程语言 > 详细

Java动态编译

时间:2019-04-25 21:32:14      阅读:92      评论:0      收藏:0      [点我收藏+]

Java动态编译

最近熟悉了一下反射,对Java的动态性有了进一步的了解,因此想实现一下用Java直接动态生成.class文件,也就是在编译完成后,运行时编译java文件

工程结构

?  helloworld tree
.
├── bin
│?? └── helloworld
│??     ├── Car.java
├── src
│?? └── helloworld
│??     ├── TestDynamicCompile.java

测试程序

TestDynamicCompile.java

package helloworld;

import java.net.MalformedURLException;
import java.util.Scanner;
import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;


public class TestDynamicCompile {

    public static void main(String[] args) throws InstantiationException, IllegalAccessException, MalformedURLException {
        Scanner scanner = new Scanner(System.in);
        String className = "helloworld.Car";//scanner.next(); // "helloworld.Car"
        scanner.close();
        
        try {
            Class.forName(className);
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            System.out.println("Class not found");
            System.out.println("dynamic compiling...");
            JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
             // 等同于javac 命令,生成的class文件默认在.java文件的同一个文件夹下
            int flag = compiler.run(null, null, null, "bin/helloworld/Car.java");
            System.out.println(flag==0? "编译成功" : "编译失败");
        }   
        try {
                Class<?> c = Class.forName(className);
                Object obj = c.newInstance();
                System.out.println(obj);
            } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    }
}

将被动态编译的程序

Car.java(放在bin/helloworld目录下)

package helloworld;

public class Car {
    private String name;
    private int ID;
    @Override
    public String toString() {
        return "name = " + name + "  ID = " + ID;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getID() {
        return ID;
    }
    public void setID(int ID) {
        this.ID = ID;
    }
    public Car(){
        this.name = "Default";
        this.ID = 123;
    }
}

编译TestDynamicCompile.java

?  helloworld tree
.
├── bin
│?? └── helloworld
│??     ├── Car.java
│??     └── TestDynamicCompile.class
├── src
│?? └── helloworld
│??     ├── TestDynamicCompile.java

可以看到Car还未被编译,TestDynamicCompile.class已经静态编译完成

运行后

?  helloworld tree
.
├── bin
│?? └── helloworld
│??     ├── Car.class
│??     ├── Car.java
│??     └── TestDynamicCompile.class
├── src
│?? └── helloworld
│??     ├── TestDynamicCompile.java

可以看到Car.class字节文件在运行时被JavaCompiler编译出来

运行输出

Class not found
dynamic compiling...
编译成功
name = Default  ID = 123

小结

Java实现了"自举",可以自己编译自己,而不用再起一个javac进程来外部编译。感觉这种注入代码的方式有一定的灵活性。

Java动态编译

原文:https://www.cnblogs.com/fanghao/p/10770924.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!