ClassLoader(Java API)

JDK API 中的东西:
public abstract class ClassLoader extends Object
class loader 是负责加载类的对象。 ClassLoader 是一个抽象类。给出一个 class 的名字, class loader 将试图定位或者获得那些构成这个 class 的定义的数据。一个典型的策略是转换该名字为文件名,然后从文件系统中读入该名称的 “class file”
 
每一个 Class 对象都含有一个指向定义这个 claass ClassLoader reference
 
数组类的 Class 对象不是由 class loader 创建的,是当需要的时候由 Java runtime 自动产生的。数组类的 class loader Class.getClassLoader() 返回,同它的成员的 classloader 的类型是一样的。如果成员是基本类型,那么该 array class 没有 class loader
 
应用程序需要实现 ClassLoader 的子类以扩展 Java 虚拟机动态加载类的方式。
 
Class loader 通常由安全管理器使用,用于指示安全域
 
ClassLoader 使用委托模型来查找 class 和资源。每一个 ClassLoader 的实例都有一个相联系的父 classloader 。当要查找一个 class 或者 resource 时,在自己开始查找之前, ClassLoader 实例将查询委托给他的父 classloader 。虚拟机建的 class loader 叫做 bootstrap class loader ,没有父类加载器,但是可以把它作为其它 classloader 的父类加载器。
 
通常情况下, Java 虚拟机以平台相关的方式从本地文件系统中加载类。例如, UNIX 中,从 CLASSPATH 环境变量定义的目录中加载类。
 
但是,一些类并非来自于文件,他们可能来自其它的资源,比如网络或者被一个应用程序生成。 defineClass 方法将一个字节数组转换为一个 Class 类的实例。这种新定义的类的实例可以通过 Class.newInstance 获得。
 
类加载器所创建对象的方法和构造方法可以引用其他类。为了确定引用的类, Java 虚拟机将调用最初创建该类的类加载器的 loadClass 方法。
 
例如,应用程序可以创建一个网络类加载器,从服务器中下载类文件。示例代码如下所示:
   ClassLoader loader = new NetworkClassLoader(host, port);
   Object main = loader.loadClass("Main", true).newInstance();
          . . .
网络类加载器子类必须定义方法findClassloadClassData,以实现从网络加载类。下载组成该类的字节后,它应该使用方法defineClass来创建类实例。示例实现如下:
     class NetworkClassLoader extends ClassLoader {
         String host;
         int port;
 
         public Class findClass(String name) {
             byte[] b = loadClassData(name);
             return defineClass(name, b, 0, b.length);
         }
         private byte[] loadClassData(String name) {
             // load the class data from the connection
              . . .
         }
     }
构造函数
ClassLoader()ClassLoader(ClassLoader parent)
方法
a)assert 
setDefaultAssertStatus(boolean enabled)
         设置确定由此类加载器加载并在将来初始化的类在默认情况下是启用还是禁用断言。
         通过调用setPackageAssertionStatussetClassAssertionStatus在每个包或类上重写此设置
setClassAssetionStatus(String className,boolean enabled)
setPackageAssertionStatus(String packagename, boolean enabled)
clearAssertionStatus(): 默认断言状态设置为false,并放弃与此loader关联的所有默认包或类的断言状态设置
b)define
defineClass() 将一个字节数组转换为Class类的实例
definePackage() 根据name在此ClassLoader中定义包。这允许类加载器定义用于他们的类的包。
包必须在定义类之前创建,包名在类加载器中必须唯一,并且一旦创建就不能重新定义或者更改。
 
c)find
findClass(String name)在父类加载器检查所请求的类之后,被loadClass调用
findLibrary(String libname)虚拟机调用此方法来查找那些属于利用这个loader加载的类的本机库
findResource()findResources()查找具有给定名称的资源。类加载器实现应重写此方法。
findLoadedClass(String name)
findSystemClass(String name) 此方法通过系统加载类来加载该类
d)get
getPackage(String name) getPackages()
返回由此类加载器或其任何祖先所定义的Package
getResource(String name) getResources(String name)
getResourceAsStream(String name)
资源可以是通过类代码与代码位置无关的方式访问的一些数据(图像、声音、文本等)
资源名称是以”/”分隔的标识资源的路径名称
此方法首先搜索资源的父类加载器,如果父类加载器为null,则搜索路径就是虚拟机的内置类加载器的路径
如搜索失败,则此方法调用findResource(String)来查找资源
getSystemResource(String name) getSystemResources(String name)
getSystemResourceAsStream(String name)
getSystemClassLoader()
getParent()
e)load
loadClass(String name) loadClass(String name, boolean resolve)
1.调用findLoadedClass(String)
2. 调用父类加载器的loadClass方法
3. 调用findClass(String)方法
如果resolve标识为true,调用resolveClass(Class)方法
f)other
resolveClass(Class c)
setSigners(Class c, Object[] signers) 设置类的签署者,应该在定义类后调用此方法
类加载是通过委托来完成的,如果ClassLoader不能找到类,会请求父代ClassLoader来执行此项任务。
所有的 ClassLoader 的根是系统 ClassLoader ,它会以缺省方式装入类,即:从本地文件系统
java.lang 包里面有个 ClassLoader 类, ClassLoader 的基本目标是对类的请求提供服务,当 JVM 需要使用类时,它根据名称向 ClassLoader 请求这个类,然后 ClassLoader 返回一个表示这个类的 Class 对象。
通过覆盖对应于这个过程不同阶段的方法,可以创建定制的 ClassLoader 。其中的 loadClass(String name,boolean resolve) 方法,该方法为 ClassLoader 的入口点。
loadClass 方法将缺省调用 findClass 方法,自编写的 ClassLoader 就是为了覆盖这两个方法。
怎样读进字节代码,构成一个类对象的:
ClassLoader 里有个方法, Class defineClass(String name,byte[] b, int off, int len) ,根据 class 字节码文件 ( Hello.class) 读进一个字节数组里, byte[] b ,并把它转化为 class 对象,这些数据可以来源于文件、网络。 defineClass 这个方法把字节代码分析成运行时数据结构、检验有效性等等。该方法被标记成是最终的,不能被覆盖。
其它的一些方法:
findSystemClass 方法:从本地系统装入文件。在本地文件系统中寻找类文件,如果存在,就使用 defineClass 将原始字节转换成 class 对象,以将该文件转换成类。
 
一、  工作流程
1)     调用 findLoadedClass(String) 来查看是否存在已经装入的类,如果已经存在,获取原始字节
2)     通过父类 ClassLoader 调用 loadClass 方法,如果父类 ClassLoader null ,那么按缺省方式装入类,即系统 ClassLoader
3)     调用 findClass String )去查找类并获取类
4)     如果 loadClass resolve 参数的值为 true ,那么调用 resolveClass 解析 Class 对象
5)     如果还没有类,返回 ClassNotFoundException
6)     否则,将类返回给调用程序
 
 
 
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值