Java动态编译和运行

一、tools.jar问题:

Java在进行动态编译的时候需要用到tools.jar资源包,此包在jdk\lib目录中。若tools.jar不存在则会出现进行编译时提示空指针异常:


Java动态编译和运行_第1张图片

对于缺少jar包,首先想到的解决办法是找到需要的jar包并且将其加入到buildpath,但是我们发现只是将tools.jar加入到java buildpath中仍然会出现空指针异常。后来经过查询相关资料,java在运行时使用的目录是jre,所以我们将tools.jar从jdk目录中复制一份到jre目录中即可,并且也不需要在java的buildpath中加入tools.jar


二、动态编译:

首先建立一个De.java文件:

public class De{
	public static void main(String[] args){
		System.out.println("hello world");
	}
}

在此处使用的是JavaCompiler进行动态编译:


compiler.run()运行后会对所指定路径的java文件进行编译,并且返回一个int类型的值。若result为0则编译成功,会在.java文件所在路径下生成.class文件


三、反射机制运行:

Java动态编译和运行_第2张图片

1、首先构建文件的目录url地址,

2、使用URLClassLoader对象的loadClass方法加载对应类

3、获取所加载类的方法

4、传入方法所需的参数通过invoke运行方法

Tips:

1、在构建URL时候一定要是URL数组。因为new URLClassLoader() 只支持URL[]的参数

2、 在使用loader.loadClass()时,传入的为类名,不要加.class后缀

3、在使用Method对象的getDeclaredMethod()方法时候第一个参数为获取方法的名字,第二个参数为本方法传入参数的类型

4、执行invoke()方法时,第一个参数为方法的返回类型。第二个参数为一个对象,例如main方法中的String[] args,它本身是一个数组,若不将其强制转换为Object,会产生异常:

Java动态编译和运行_第3张图片


完整代码如下:

package com.xm.demo;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;

import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
/**
 * 
* @ClassName: Test 
* @Description: 动态编译运行的测试(这里用一句话描述这个类的作用) 
* @author xiaomu 
* @date 2018年1月5日 上午8:37:04 
*
 */
//将所有警告取消
@SuppressWarnings("all")
public class Test {
public static void main(String[] args) throws MalformedURLException, ClassNotFoundException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
	JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
	int result = compiler.run(null, null, null, "G:/demo/De.java");
	System.out.println(result==0?"成功":"失败");
	
	
	URL[] urls = new URL[] {new URL("file:/"+"G:/demo/")};
	URLClassLoader loader = new URLClassLoader(urls);
	Class c = loader.loadClass("De");
	Method m = c.getDeclaredMethod("main", String[].class);
	//通过Object把数组转化为参数
	m.invoke(null, new String[] {});
	
}
}



你可能感兴趣的:(学习笔记)