Java动态编译和类的重新加载
来源:互联网 发布:神州量子网络 招聘 编辑:程序博客网 时间:2024/05/16 07:09
注意:
1.动态编译的class文件不要放到jre的ClassPath中,在jre在ClassPath中找到的类只会加载一次。
2.使用反射获取类的时,如果需要获取最新生成的,需要重新实例化一个类加载器,因为旧的类加载器已经加载过这个类,再次加载只会加载上次那个。而重新实例化的类加载器没有加载过这个类,所以会重新去定义、链接和加载。
Main.java
public class Main {public static void main(String[] args) {String fullClassName = "MyObj";String code = "public class MyObj implements MyInterface{public void sayHello(){System.out.println(666);}}";String code_2 = "public class MyObj implements MyInterface{public void sayHello(){System.out.println(777);}}";String code_3 = "public class MyObj implements MyInterface{public void sayHello(){System.out.println(888);}}";load(code,fullClassName);load(code_2,fullClassName);load(code_3,fullClassName);}private static void load(String code, String fullClassName) {new MyClassCompiler(fullClassName, code).compile();try {MyInterface myObj = (MyInterface) new MyClassLoader().loadClass(fullClassName).newInstance();myObj.sayHello();} catch (InstantiationException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
MyClassCompiler.java
import java.io.File;import java.io.IOException;import java.net.URI;import java.net.URISyntaxException;import java.util.Arrays;import javax.tools.JavaCompiler;import javax.tools.JavaCompiler.CompilationTask;import javax.tools.JavaFileObject;import javax.tools.JavaFileObject.Kind;import javax.tools.SimpleJavaFileObject;import javax.tools.ToolProvider;public class MyClassCompiler {private String simpleClassName;private String code;private String classPath = System.getProperty("user.dir") + File.separator + "myFolder";public MyClassCompiler(String simpleClassName, String code) {this.simpleClassName = simpleClassName;this.code = code;}public boolean compile() {try {JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();JavaFileObject javaFile = new SimpleJavaFileObject(new URI(simpleClassName + ".java"), Kind.SOURCE) {@Overridepublic CharSequence getCharContent(boolean arg)throws IOException {return code;}};CompilationTask task = compiler.getTask(null, null, null,Arrays.asList("-d", classPath), null,Arrays.asList(javaFile));return task.call();} catch (URISyntaxException e) {e.printStackTrace();return false;}}public String getSimpleClassName() {return simpleClassName;}public void setSimpleClassName(String simpleClassName) {this.simpleClassName = simpleClassName;}public String getCode() {return code;}public void setCode(String code) {this.code = code;}public String getClassPath() {return classPath;}public void setClassPath(String classPath) {this.classPath = classPath;}}
MyClassLoader.java
import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;public class MyClassLoader extends ClassLoader {private boolean alwaysDefineClass = true;private String classPath = System.getProperty("user.dir") + File.separator + "myFolder";@Overrideprotected Class<?> findClass(String fullClassName)throws ClassNotFoundException {Class<?> clazz = null;// clazz = findLoadedClass(fullClassName);// if(alwaysDefineClass || clazz == null){byte[] raw = readClassBytes(fullClassName);clazz = defineClass(fullClassName, raw, 0, raw.length);resolveClass(clazz);// }return clazz;}private byte[] readClassBytes(String fullClassName) {byte[] raw = null;InputStream stream = null;File file = new File(classPath + File.separator+ fullClassName.replaceAll("\\.", "/") + ".class");try {stream = new FileInputStream(file);raw = new byte[(int) file.length()];stream.read(raw);} catch (Exception e) {} finally {try {stream.close();} catch (IOException e) {}}return raw;}public boolean isAlwaysDefineClass() {return alwaysDefineClass;}public void setAlwaysDefineClass(boolean alwaysDefineClass) {this.alwaysDefineClass = alwaysDefineClass;}public String getClassPath() {return classPath;}public void setClassPath(String classPath) {this.classPath = classPath;}}
interface.java
public interface MyInterface { public void sayHello();}
- Java动态编译和类的重新加载
- 关于 动态库的编译和加载
- 动态编译加载java文件类
- java动态编译,反射加载类
- 重新编译ClassLoader记录被加载的类
- 动态编译 Java 文件 与 动态加载 Java 类
- 动态生成java、动态编译、动态加载
- JAVA的动态编译和静态编译
- 重新演绎动态编译类,打造灵活多变的系统
- java 编译和加载和执行类的全过程
- Java的类类型和类的动态加载
- java动态编译动态加载方法
- 从String中动态(内存中)编译和加载java类
- java类的动态加载
- Java Class类的使用 和 动态加载类
- java jar的动态加载和释放
- JAVA下进行动态编译加载的实例
- JAVA类的静态加载和动态加载以及NoClassDefFoundError和ClassNotFoundException
- c语言易错题总结
- 每个程序员都应该给自己写本书
- Linux在指定目录下查找包含指定字符串的文件
- UIWebView详解
- 火狐浏览器单击链接总是在一个新的标签页打开的设置方法
- Java动态编译和类的重新加载
- 用Java编写获取文件MD5小工具
- 电池 电量计(MAX17040)驱动分析篇
- 网卡问题
- 【iOS开发】---- ALAsset,ALAssetsLibrary,ALAssetsgroup常见属性及用法
- 以前的博客
- 设计子线程的管理器
- jdk各版本的区别
- IT职业规划与行业分析