Java基础加强之类加载器
作者:网络转载 发布时间:[ 2013/12/24 11:05:26 ] 推荐标签:Java 类加载器
3.自定义类加载器
JVM中除了根类加载器之外的所有类加载器都是classloader的子类实例,我们完全可以通过扩展ClassLoader的子类,并重写ClassLoader所包含的的方法来实现自定义类 加载器,ClassLoader有两个关键的方法:loadClass(),findClass()。
不过我们一般推荐重写findClass()方法,而不是loadClass()方法,因为重写findClass()可以避免覆盖默认类加载器的父类委托,缓存机制两种策略。
下面是我自己编写的一个类加载器:
|
package snippet;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
/**
*
* @author Administrator
*自定义类加载器
*/
public class MyClassLoader extends ClassLoader {
// 获取java源文件的二进制码
public byte[] getBytes(String filename){
File file = new File(filename);
InputStream ips=null;
byte[] b = new byte[(int) file.length()];
try {
ips = new FileInputStream(file);
int raw =ips.read(b);
if(raw!=file.length()){
throw new IOException("无法完整读取文件");
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
if(ips!=null){
try {
ips.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return b;
}
public boolean compile(String javaFile){
System.out.println("正在编译");
Process p=null;
try {
//调用系统javac命令
p=Runtime.getRuntime().exec("javac" + javaFile);
try {
p.waitFor();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int ret = p.exitValue();
return ret==0;
}
@Override
protected Class<?> findClass(String name) {
Class<?> clazz=null;
String fileStub = name.replace(".", "/");
String javaFileName = fileStub + ".java";
String classFileName = fileStub + ".class";
File javaFile = new File(javaFileName);
File classFile = new File(classFileName);
//如果java源文件存在并且class文件不存在,或者java源文件比class文件修改的时间晚
if(javaFile.exists()&&(!classFile.exists()||javaFile.lastModified()>classFile.lastModified())){
if(!compile(javaFileName)||!classFile.exists()){
try {
throw new ClassNotFoundException("未发现class文件");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//如果class文件已经存在,那么直接生成字节码
if(classFile.exists()){
byte[] b = getBytes(classFileName);
clazz = defineClass(name, b, 0, b.length);
}
//如果为空,标明加载失败
if(clazz==null){
try {
throw new ClassNotFoundException(name);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return clazz;
}
}
|
上面代码重写了findClass方法,通过重写该方法可以实现自定义的类加载机制。
学习总结:1.了解了JVM三种类加载器(根类加载器,系统类加载器,扩展类加载器),明白了三种类加载器的作用和范围
2.学习了JVM三种类加载机制(父类委托,缓存,全盘负责)
3.学习了如何自定义类加载器,通过继承ClassLoader类,特别要注意两个关键方法:loadClass()和findClass()两种方法的机制和不同。
本文内容不用于商业目的,如涉及知识产权问题,请权利人联系SPASVO小编(021-61079698-8054),我们将立即处理,马上删除。
相关推荐
Java性能测试有哪些不为众人所知的原则?Java设计模式??装饰者模式谈谈Java中遍历Map的几种方法Java Web入门必知你需要理解的Java反射机制知识总结编写更好的Java单元测试的7个技巧编程常用的几种时间戳转换(java .net 数据库)适合Java开发者学习的Python入门教程Java webdriver如何获取浏览器新窗口中的元素?Java重写与重载(区别与用途)Java变量的分类与初始化JavaScript有这几种测试分类Java有哪四个核心技术?给 Java开发者的10个大数据工具和框架Java中几个常用设计模式汇总java生态圈常用技术框架、开源中间件,系统架构及经典案例等

sales@spasvo.com