Class Loading ---(类装载机制,开发者不得不知道的故事) --上篇

原创 2005年05月29日 01:07:00
 
也许你认为Class Load是一个高级话题,不管怎样,作为开发者你还是要了解它。
本文基于最新得JDK5,然后将将诉的内容都包含了最基本的原理,希望你能更加深入了解自己所使用得语言。
 
 

理解CLassLoader
 
如果你自己定义叻一个 org.test.Object 。
你在程序中这样写:
import ort.test.Object
Object o = new String(); 
也许你欣然以为这样写没问题,但实际上你错了。 
这样是不正确的,会报 ClassCastException,
一个Class在JVM中得标识呢是由它得 PackAge 和 类名决定得。 也就是它得名称空间。
 org.test.Object 可不是  java.lang.Object
 
在java中呢,每个类都是java.lang.Class得实例。也就是说。
 
 
在JVM中。所有得类都由 java.lang.ClassLoader.(或者是它得子类开发者自己添加得),我们在启动得时候都是借力于JAVA_HOME/jre/rt.jar。  不过我们发现JDK这里并没有任何文档介绍bootstrap.jar。 实际上bootstrap Class Loader是JDK之外得,它得方式和JVM的是不一样的。(本文不做介绍)
  • java.net.URLClassLoader
  • java.security.SecureClassLoader
  • java.rmi.server.RMIClassLoader
  • sun.applet.AppletClassLoader
Class Loaders工作原理
 
  除了bootstrap之外,所有的Classloader都有个父类Class Loader ,他们都是instanceof java.lang.ClassLoader
 
来看看JDK1.5中的工作原理。
假如有个方法loadClass
 
protected synchronized Class<?> loadClass
    (String name, boolean resolve)
    throws ClassNotFoundException{

    // First check if the class is already loaded
    Class c = findLoadedClass(name);
    if (c == null) {
        try {
            if (parent != null) {
                c = parent.loadClass(name, false);
            } else {
                c = findBootstrapClass0(name);
            }
        } catch (ClassNotFoundException e) {
            // If still not found, then invoke
            // findClass to find the class.
            c = findClass(name);
        }
    }
    if (resolve) {
    resolveClass(c);
    }
    return c;
}

 
那么Set它父类的方式有两种。
public class MyClassLoader extends ClassLoader{
    public MyClassLoader(){
        super(MyClassLoader.class.getClassLoader());
    }
}
或者
public class MyClassLoader extends ClassLoader{
    public MyClassLoader(){
        super(getClass().getClassLoader());
    }
}
 
这里是首选第一种。
因为getClass()是在构造函数内部得方法,所以必须要有构造函数代码存在,但是如果不存在,那就找父类得classloader 一直找啊找,直至找到到findBootstrapClass, 如果它也不存在得话,那时候findClass()方法会被调用执行。。到那时候会报一个ClassNotFoundException
 
来看看findClass()得代码

    protected Class<?> findClass(String name)
        throws ClassNotFoundException {
        throw new ClassNotFoundException(name);
    }
 
在findClass() 方法内 class loader要取得到得字节码(就是.class文件里得内容),然而不不一定就是.class文件, 这些字节码可以来自本地,也可以是系统,网络(借着这个你可以理解一下Cobra,RMI),也可以是用BCEL(Apache一个基于字节码得一个引擎库) ...等等。 一但字节码找到了。那时候就开始执行defineClass()方法。那时候会定义出一个类的实例来。
 
如果有两个ClassLoader 实例化两个相同得代码,defineClass()定义得两个类也是不同得。详细请看(Java language specification

    protected Class<?> findClass(String name)
        throws ClassNotFoundException {
        throw new ClassNotFoundException(name);
    }
 
在findClass() 方法内 class loader要取得到得字节码(就是.class文件里得内容),然而不不一定就是.class文件, 这些字节码可以来自本地,也可以是系统,网络(借着这个你可以理解一下Cobra,RMI),也可以是用BCEL(Apache一个基于字节码得一个引擎库) ...等等。 一但字节码找到了。那时候就开始执行defineClass()方法。那时候会定义出一个类的实例来。
 
如果有两个ClassLoader 实例化两个相同得代码,defineClass()定义得两个类也是不同得。详细请看(Java language specification
 
 
 
 
下图展示了一个MyMainclass.class如何装载执行。(由多个classLoader加载同一个Target.class),----和我们想象中有差别得是,它首先是由于BootStarpClassLoader载入得。
根据上面得解析,既然两个classLoader()载入Target.class得字节码 ,那defineClass()就会产品两个class得定义得。
 
所以很容易得出结论Target target3 = (Target) target2; 是不能被执行地。
 
 
 
 
具体请看Inside Class Loaders(Andreas Schaefer)

Class Loading ---(类装载机制,开发者不得不知道的故事)

也许你认为Class Load是一个高级话题,不管怎样,作为开发者你还是要了解它。 本文基于最新得JDK5,然而将诉的内容却包含了最基本的原理,希望你能更加深入了解自己所使用得语言。     理解CL...
  • vvggsky
  • vvggsky
  • 2006年12月14日 17:52
  • 655

Class Loading ---(类装载机制,开发者不得不知道的故事)

也许你认为Class Load是一个高级话题,不管怎样,作为开发者你还是要了解它。 本文基于最新得JDK5,然而将诉的内容却包含了最基本的原理,希望你能更加深入了解自己所使用得语言。  理解CLass...
  • totodo
  • totodo
  • 2005年01月28日 13:15
  • 5690

Class Loading ---(类装载机制,开发者不得不知道的故事) --上篇

 也许你认为Class Load是一个高级话题,不管怎样,作为开发者你还是要了解它。 本文基于最新得JDK5,然后将将诉的内容都包含了最基本的原理,希望你能更加深入了解自己所使用得语言。  理解CLa...
  • JEGarden
  • JEGarden
  • 2005年02月04日 16:56
  • 1376

Class Loading ---(类装载机制,开发者不得不知道的故事) --下篇

如何构造使用自定义的ClassLoader既然自定义的ClassLoader,能解决上述问题,那接下去看看,我们如何来使用自定义的ClassLoader。结合本文种的原码---(在differentv...
  • start_java
  • start_java
  • 2005年06月27日 01:18
  • 1054

Class Loading ---(类装载机制,开发者不得不知道的故事) --下篇

如何构造使用自定义的ClassLoader既然自定义的ClassLoader,能解决上述问题,那接下去看看,我们如何来使用自定义的ClassLoader。结合本文种的原码---(在differentv...
  • totodo
  • totodo
  • 2005年01月28日 21:48
  • 2013

Class Loading ---(类装载机制,开发者不得不知道的故事) --中篇

  我们是否需要自定义的ClassLoader?     理由之一: 如果我们自定义了ClassLoader,那我们便可以控制JVM的加载动作了。      上面说一个class标识是由于packag...
  • totodo
  • totodo
  • 2005年01月28日 21:37
  • 1873

Class Loading ---(类装载机制,开发者不得不知道的故事) --中篇

我们是否需要自定义的ClassLoader?     理由之一: 如果我们自定义了ClassLoader,那我们便可以控制JVM的加载动作了。      上面说一个class标识是由于package+...
  • dazern
  • dazern
  • 2005年05月29日 01:07
  • 869

JVM 之 类的装载机制

看到网上有一道面试题:能不能装载自定义的 java.lang.String? 答案是否定的,我们能自定义一个java.lang.String,但是加载不进来。 我相信很多人在网上看到这样的答案“可以...
  • MakeContral
  • MakeContral
  • 2017年10月28日 12:28
  • 210

Java你可能不知道的事系列1

概述本类文章会不段更新分析学习到的经典面试题目,在此记录下来便于自己理解。如果有不对的地方还请各位观众拍砖。 今天主要分享一下常用的字符串的几个题目,相信学习java的小伙伴们对String类是再熟...
  • yissan
  • yissan
  • 2016年03月06日 00:39
  • 2112

五分钟了解你不得不知道的人工智能热门词汇

编者按:大数据和人工智能的浪潮正在席卷全球,众多热门词汇蜂拥而至:人工智能(Artificial Intelligence)、大数据(Big Data)、云计算(Cloud Computing)、...
  • Y2c8YpZC15p
  • Y2c8YpZC15p
  • 2017年10月10日 00:00
  • 2350
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Class Loading ---(类装载机制,开发者不得不知道的故事) --上篇
举报原因:
原因补充:

(最多只允许输入30个字)