论坛首页 Java版

关于自定义类加载器ClassLoader的一个奇怪的现象??

浏览 513 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
最后更新时间:2007-09-10 关键字: J2SE
主要的问题:
疑问:1。 为什么我自定了加载类还没加载 系统的加载器就可以发现类的存在。
       2。 可是在第二个输出信息中为什么又变成了 我自定义的加载器
       3。 更奇怪的是当我再次new 又会由系统加载器再次进行加载。
package classLaoder;
import java.io.*;
public class UserClassLoader extends ClassLoader {



public synchronized Class loadClass(String className, Boolean flag ) throws ClassNotFoundException {

//check the class weather  had been loaded
Class class1=null; //= Class.forName(className);
if(class1!= null)
System.out.println(class1.toString());
//return class1;

// check the class has not been loaded by the System ClassLoader

try{
class1 = super.findSystemClass(className);
if(class1!=null)
System.out.println(class1.toString());
}catch(ClassNotFoundException _ex){
System.out.println(">> Not a system class.");
}
byte abyte0[] = getClassBytes(className);
if(abyte0 == null){
throw new ClassNotFoundException();
}

class1 = defineClass(null, abyte0, 0, abyte0.length);
if(class1 == null){
throw new ClassFormatError();
}

if(flag){
resolveClass(class1);
}
System.out.println(">> Returning newly loaded class.");
return class1;


}

private byte[] getClassBytes(String className){
String path="D://Program//NASA Program//ClassLoaderTest//classLaoder//";
className=path+"UserClass.class";
File f=new File( className );
byte[] b = new byte[(int)f.length()];

try{
InputStream input= new FileInputStream( f );
input.read(b);
System.out.println(b);
}catch(IOException e){
e.printStackTrace();
}
return b;
}
}

接着编写了一个测试程序:
package classLaoder;

public class ClassLoaderTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
UserClassLoader loader= new UserClassLoader();
Object ob;
try{
ob=loader.loadClass("classLaoder.UserClass", true).newInstance();
System.out.println("the class UserClass is loader by  "+ob.getClass().getClassLoader() );
}catch(Exception e){
e.printStackTrace();
}
UserClass user=new UserClass();
System.out.println("now the class UserClass is loader by  "+user.getClass().getClassLoader() );
}
}
(其中的 UserClass 用于测试的一个非常简单的自定义的类)

测试的结果:
class classLaoder.UserClass
[B@addbf1
>> Returning newly loaded class.
the class UserClass is loader by  classLaoder.UserClassLoader@42e816
now the class UserClass is loader by  sun.misc.Launcher$AppClassLoader@11b86e7

疑问:1。 为什么我自定了加载类还没加载 系统的加载器就可以发现类的存在。
      2。 可是在第二个输出信息中为什么又变成了 我自定义的加载器
      3。 更奇怪的是当我再次new 又会由系统加载器再次进行加载。
   
最后更新时间:2007-09-11
简单回答一下:
1. 如果你的类(UserClass )已存在于classpath中,系统的类加载器当然可以发现它的存在。

2. 你使用了自定义的类加载器去加载类,当然输出信息显示是你的类加载器加载了此类。
    ob=loader.loadClass("classLaoder.UserClass", true).newInstance();

3. 你使用new 来生成类的实例,这个是使用当前线程默认的类加载器来加载需要实例化的类的。而你此时的默认类加载器是系统加载器。可以使用Thread.getContextClassLoader(),Thread.setContextClassLoader()来操作当前线程的默认类加载器。
   
0 请登录后投票
最后更新时间:2007-09-11
好象很多情况即使把自定意的classloader通过Thread.setContextClassLoader()给了当前线程,但很多情况下使用到classloader的时候都不是从当前线程拿,还是拿的启动jvm的loader,有谁很清楚能否讲讲了
   
0 请登录后投票
论坛首页 Java版

跳转论坛:
JavaEye推荐