认识java的类加载器(二)
来源:互联网 发布:java 日期转换字符串 编辑:程序博客网 时间:2024/04/24 03:26
2、如何实现自定义的编译器
通常,一个编译器不仅仅要求编译您当前要编译的类,它必须先编译它说依赖的其他类,等其依赖的类加载进来后才能编译当前类,即其必须逐个编译它所依赖的每一个类。而且加载前必须把原代码文件与存在的编译文件的修改时间比较,如果原代码的修改时间后于编译过的文件,那么必须重新编译原文件。
import java.io.*; //自定义类加载编译器 public class Compilation extends ClassLoader{ //加载类的二进制代码 private byte[] loadClassData(String fileName)throws IOException{ //读取类文件 File file = new File(fileName); if(!file.exists()){ return null; } FileInputStream input = new FileInputStream(file); long length = file.length(); byte[] bt = new byte[(int)length]; int rl = input.read(bt); if(rl != length){ throw new IOException("不能读取所有内容"); } input.close(); return bt; } //编译原代码文件 private boolean compile( String javaFile ) throws IOException { // 知会用户在编译的文件 System.out.println( "编译类 : "+javaFile ); // 启动java编译器 Process p = Runtime.getRuntime().exec( "javac "+javaFile ); // 等待编译完成 try { p.waitFor(); } catch( InterruptedException e ) { System.out.println("编译失败"); } // 返回子进程的出口值,值 0 表示正常终止。 int ret = p.exitValue(); return ret==0; } public Class loadClass( String name, boolean resolve ) throws ClassNotFoundException { System.out.println("加载类: "+ name); //目标class对象 Class clas = null; // 查看是否已经加载该类 clas = findLoadedClass( name ); //把类的包结构转化成系统文件目录 String fileStub = name.replace( '.', '/' ); String javaFilename = fileStub+".java"; String classFilename = fileStub+".class"; File javaFile = new File( javaFilename ); File classFile = new File( classFilename ); // 查看是否是最新编译的文件 if (javaFile.exists() && (!classFile.exists() || javaFile.lastModified() > classFile.lastModified())) { try { // 编译文件 if (!compile( javaFilename ) || !classFile.exists()) { throw new ClassNotFoundException( "没找到类文件: "+javaFilename ); } } catch( IOException ie ) { throw new ClassNotFoundException( "找不到类 : " + name); } } if(classFile.exists()){ //获取字节码 try { byte raw[] = loadClassData(classFilename); // 转化成class对象 clas = defineClass( name, raw, 0, raw.length ); } catch( IOException e){ System.out.println("转化成class对象失败:" + classFilename); } } // 查找classpath中是否存在 if (clas == null) { clas = findSystemClass(name); } // 是否需要分析字节码 if (resolve && clas != null) resolveClass( clas ); // 找不到该类 if (clas == null) throw new ClassNotFoundException( "类不存在" ); return clas; } } public class Pig{ public Pig(){ new PigSon(); } } public class PigSon{ public PigSon(){ try{ Class.forName("PigSon2"); }catch(Exception e){ System.out.println(e.getMessage()); } System.out.println("This is PigSon"); } } public class PigSon2{ public PigSon2(){ System.out.println("This is PigSon2"); } } public class TestCompilation{ public static void main(String[] args){ Compilation cp = new Compilation(); try{ cp.loadClass("Pig",true).newInstance(); }catch(Exception e){ System.out.println(e.getMessage()); } } }
注意运行时不要编译Pig,PigSon,PigSon2,这样才能够调用自定义的编译器。
加载类: Pig 编译类 : Pig.java 加载类: java.lang.Object 加载类: java.lang.Throwable 加载类: java.lang.Exception 加载类: PigSon 加载类: java.lang.Class 加载类: PigSon2 编译类 : PigSon2.java 加载类: java.lang.System 加载类: java.io.PrintStream This is PigSon This is a pig |
- 认识java的类加载器(二)
- 对于java类加载器的认识
- 对Java类加载器的认识
- 认识java的类加载器(一)
- 对于java类加载器的认识(1)
- 认识 Java类加载器
- 黑马程序员:对Java类加载器体系的认识
- 对于java类加载器的认识(1)
- 对于java类加载器的认识(2)
- Java 静态加载类与动态加载类(初步认识Java的反射)
- java类加载器(二)
- 从头认识java-6.7 初始化与类的加载
- Java 类加载器(二)-类加载器的特性
- 初步认识类加载器
- 初学Java的类加载与反射机制(二)
- background的认识(二)
- JAVA多线程变量的深入认识(二)
- java类的认识
- SOA与整合问题均须服务于业务
- 解决ORA-12560 TNS 协议适配器错误
- 龙庆峡的寺庙,房地产商,及印度的软件开发模式,
- AIX下C/C++源程序自动排版
- Stray Birds(22-28)
- 认识java的类加载器(二)
- 正则表达式
- java循环遍历文件夹及其子文件夹和文件
- winform c# 实现被访问的网站自动登录
- 破解网站发布系统 ASP生成静态页面方法
- 近期工作学习记录
- Google Maps by asp.net API集成
- oracle数据库性能监视小软件
- Javascript轮显效果