一直以为我们写好的程序都需要预先编译好,然后再运行,直到今天在看书的时候才看到书上说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是否提供支持了。