2014-09-21 47 views
2

这是一个使用类加载器的例子,您可以看到输出。为什么objobj2的类加载器不同?我知道'父类加载器'的想法。JVM中的类加载器

public class jvm_77{ 

    public static void main(String[] args) throws Exception{ 
     ClassLoader myLoader = new ClassLoader(){ 

      public Class<?> loadClass(String name) throws ClassNotFoundException{ 
       try 
       { 
        String fileName = name.substring(name.lastIndexOf(".")+1)+".class"; 
        InputStream is = getClass().getResourceAsStream(fileName); 
        if(is == null) 
        { 
         return super.loadClass(name); 
        } 
        byte[] b = new byte[is.available()]; 
        is.read(b); 
        return defineClass(name,b,0,b.length); 
       }catch(IOException e) 
       { 
        throw new ClassNotFoundException(name); 
       } 
      } 

     }; 

     Object obj = myLoader.loadClass("Chapter7_ClassLoader.jvm_77").newInstance(); 
     jvm_77 obj2 = new jvm_77(); 

     System.out.println(obj.getClass().getClassLoader()); //[email protected] 
     System.out.println(obj2.getClass().getClassLoader()); //[email protected] 

     System.out.println(obj.equals(obj2));//false 
     System.out.println(obj instanceof Chapter7_ClassLoader.jvm_77);//false 
     System.out.println(obj2 instanceof Chapter7_ClassLoader.jvm_77);//true 
    } 

} 

回答

2

为什么OBJ的类加载器和obj2的类装入器有什么不同?

该行创建了标准类加载器加载的jvm_77类的实例。

jvm_77 obj2 = new jvm_77(); 

此行是创建位于由您定制的ClassLoader的jvm_77类的一个实例。

Object obj = myLoader.loadClass("Chapter7_ClassLoader.jvm_77").newInstance(); 

所以基本上,你问也是为什么两种方法不会给你同样的Class对象。而这个问题的答案是,你已经在你的类加载器来实现loadClass方式:

  • loadClass方法的默认行为是:

    1. 尝试父类加载器
    2. 如果失败,检查我们是否已经加载类
    3. 如果失败,找到资源并加载类。
  • 你的类加载器的loadClass方法做到这一点:

    1. 试图寻找资源
    2. 如果资源查找成功,加载资源
    3. 如果资源查找失败,请尝试父类加载器。

显然,你的定制ClassLoader是要尝试定义一个新的类...如果可能的话。显然,它是成功的。


总之,类加载器的,因为你实现loadClass方法的方法是在不同的输出。