zoukankan      html  css  js  c++  java
  • Java动态编译

    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进程来外部编译。感觉这种注入代码的方式有一定的灵活性。

  • 相关阅读:
    如何判断两个IP是否在同一网段
    http://blog.csdn.net/a9529lty/article/details/6454156
    http://blog.csdn.net/a9529lty/article/details/6454145
    tomcat下配置https环境(windows环境)
    hosts文件配置及主要作用
    函数y=sin(1/x)曲线
    求证:a^4+b^4 ≧a^3*b+a*b^3
    三种双二次曲线
    已知m和n是两个整数,并且m^2+mn+n^2能被9整除,试证m,n都能被3整除。
    x为正变数,求y=x^3/(x^4+4)的最大值
  • 原文地址:https://www.cnblogs.com/fanghao/p/10770924.html
Copyright © 2011-2022 走看看