jvm解析二(自定义加载器)

[b]自定义加载器[/b]<code>
3个类LoaderTest01.java, LoaderTest02.java,MyClassLoader.java
1, MyClassLoader
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class MyClassLoader extends ClassLoader{

private String name;
private String path;
private final String fileType=".class";
public MyClassLoader(String name){
super();
this.name=name;
}
public MyClassLoader(ClassLoader parent,String name){
super(parent);
this.name=name;
}
@Override
public String toString() {

return this.name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getFileType() {
return fileType;
}

private byte[] loadClassData(String name) {
InputStream in=null;
byte [] data=null;
ByteArrayOutputStream bs=null;
try{
System.out.println("name="+this.name);
this.name=this.name.replace(".", "\\");
in=new FileInputStream(new File(path+name+fileType));
bs=new ByteArrayOutputStream();
int k=0;
while((k=in.read())!=-1){
bs.write(k);
}
data=bs.toByteArray();
}catch(Exception e){
e.printStackTrace();
}finally{
try {
in.close();
bs.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

return data;
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
byte [] data=this.loadClassData(name);

return this.defineClass(name, data, 0,data.length);
}

public static void main(String args[]) throws ClassNotFoundException, InstantiationException, IllegalAccessException{
MyClassLoader loader01=new MyClassLoader("loader01");
loader01.setPath("d:\\loader\\lib1\\");

MyClassLoader loader02=new MyClassLoader(loader01,"loader02");
loader02.setPath("d:\\loader\\lib2\\");

MyClassLoader loader03=new MyClassLoader(null,"loader03");
loader03.setPath("d:\\loader\\otherlib3\\");

load(loader02);
load(loader03);
}

public static void load(ClassLoader loader) throws ClassNotFoundException, InstantiationException, IllegalAccessException{
Class c=loader.loadClass("LoaderTest01");
Object object=c.newInstance();
}
}

2, LoaderTest01
public class LoaderTest01 {

public LoaderTest01() {
System.out.println("LoaderTest01 is loader by :"+this.getClass().getClassLoader());
new LoaderTest02();
}

}

3, LoaderTest02
public class LoaderTest02 {

public LoaderTest02() {
System.out.println("LoaderTest02 is loader by :"+this.getClass().getClassLoader());

}

}

第一种情况文件按照下面位置放置
[img]http://dl.iteye.com/upload/attachment/0068/1698/48ea26e6-36d7-3957-b800-d5e722eb19f1.png[/img]
运行结果如下:
[img]http://dl.iteye.com/upload/attachment/0068/1702/ac44d79d-964e-39c5-a536-1ac77578b70c.png[/img]
分析:当执行load(loader02)这句语句的时候,会优先去找它的父加载器loader01, 而loader01又回去找它的父类是系统加载器,系统加载器会根据classpath来查找所要加载的类,发现没有,接着由loader01去加载,loader01加载的时候找到文件执行接下操作,而LoaderTest01里主动使用了new LoaderTest02(), LoaderTest02也会根据上面的方式去找,跟LoaderTest01结果是一样的。
当执行load(loader03)这句语句的时候,由于父类加载器是null默认为根加载器,根加载器会去sun.boot.class.path的里面去找没有找到,最后由loader3自己去加载。
第二种情况文件按照下面位置放置
[img]http://dl.iteye.com/upload/attachment/0068/1704/15e658da-9b3f-31dc-ae7c-cf8b3e329319.png[/img]
运行结果如下:
[img]http://dl.iteye.com/upload/attachment/0068/1706/5be57969-ae50-3a72-ba40-0333e1bbc845.png[/img]
分析:当执行load(loader02)的时候,会优先去找它的父加载器loader01, 而loader01又回去找它的父类是系统加载器,系统加载器会根据classpath来查找所要加载的类,发现没有,接着由loader01去加载,loader01加载的时候找到文件执行接下操作,而LoaderTest01里主动使用了new LoaderTest02(), LoaderTest02也会执行上面同样的步骤, 但是LoaderTest01和LoaderTest02位于2个不同的加载器空间下,而他们之间是互相不可见的(他们的父子关系并不是继承,也有可能是组合,但是他们都是系统加载器的子类,对系统加载器里的资源都是共享的),所以在Loader01加载器加载的时候无法获取LoaderTest02
第三种情况:
[img]http://dl.iteye.com/upload/attachment/0068/1708/0c31ce60-9f10-32ec-b310-8da6225e33fd.png[/img]
运行结果如下:
[img]http://dl.iteye.com/upload/attachment/0068/1710/50e3d0cb-5f0f-35da-a10d-87e428ca9091.png[/img]
分析:当执行load(loader02)的时候,会优先去找它的父加载器loader01, 而loader01又回去找它的父类是系统加载器,系统加载器会根据classpath来查找所要加载的类,并在当前目录下发现了这2个类,并执行操作,前2个加载器均为系统加载器,虽然lib1和lib2下2个文件在不同的类加载器空间下,但是实际执行并不需要它们,在系统一级已经执行完毕,而第三个,当执行load(loader03)的时候,父加载器null默认为根加载器,根加载器无法在相应的目录里找到相应的文件,于是交由其他加载器实现,而此时loader03加载器在相应的otherlib3下也无法找到相应的文件于是报错。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值