一直以为我们写好的程序都需要预先编译好,然后再运行,直到今天在看书的时候才看到书上说JAVA1.6之后可以动态的编译JAVA文件,这着实让我高兴了一把,为什么这么兴奋呢,我一心想着能用技术实现动态更新APK,不用一次次的发布打包,有了动态加载,可以说是成功了一大截。于是赶紧试试:
package com.sahadev;import java.io.IOException;
import java.lang.reflect.Constructor;
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.JavaCompiler.CompilationTask;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;public class Main {public static String FILE_PATH = "D:\\Users\\Sahadev\\workspace\\JavaDes\\src\\com\\sahadev\\Hello.java";public static void main(String[] args) {// 动态编译JAVA文件JavaCompiler jCompiler = ToolProvider.getSystemJavaCompiler();StandardJavaFileManager standardFileManager = jCompiler.getStandardFileManager(null, null, null);Iterable<? extends JavaFileObject> javaFileObjects = standardFileManager.getJavaFileObjects(FILE_PATH);CompilationTask task = jCompiler.getTask(null, standardFileManager, null, null, null, javaFileObjects);task.call();try {standardFileManager.close();} catch (IOException e) {}try {// 进行类装载URL[] urls = new URL[] { new URL("file:/" + FILE_PATH) };URLClassLoader loader = new URLClassLoader(urls);Class<?> loadClass = loader.loadClass("com.sahadev.Hello");loader.close();// 实例化对象Constructor<?> constructor = loadClass.getConstructor();Object newInstance = constructor.newInstance();// 调用对象的方法Method method = loadClass.getMethod("printf");method.invoke(newInstance);} catch (MalformedURLException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();} catch (NoSuchMethodException e) {e.printStackTrace();} catch (SecurityException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}
}
Hello.java:
package com.sahadev;public class Hello {public void printf() {System.out.println("HelloWorld!");}
}
运行结果:
HelloWorld!
运行成功!
其实在Android上是用不了这种办法的,Android提供的Java库里面并没有这种方法,只能看看以后Android是否提供支持了。