8.1.2类装载器与双亲委派横型

8.1.2类装载器与双亲委派横型

在第3章曾讲过,1.2版本中引人了类装载器的形式化双亲委派模型。虽然老式版本(即12 版本之前)编写的类装载器无法享受双亲委派模型的好处,但仍然可以在1.2版本中使用,1.2版 本及更高版本中推荐使用双亲委派模型创建类装载器。1.2版本中每一个用户自定义的类装载器在创建时被分配一个“双亲”类装载器。如果没有显式地传递一个双亲类装载器给用户自定义 的类装载器的构造方法,系统类装载器就默认被指定为双亲。或者,在调用用户自定义的新类 装载器的时候,双亲装载器可以被显式地传递过去。如果传递到构造方法的是一个已有的用户 自定义类装载器的引用,该用户自定义装载器就作为双亲。如果向构造方法传递了null,启动类 装载器就是双亲。

为了更好地理解双亲委派模型,假设一个Java程序创建了一个名为“Grandma”的自定义类 装载器。因为程序传递了null到Grandma的构造方法,Grandma的双亲就是启动类装载器。过了 —段时间,程序创建了另一个名为“Mom”的类装载器。因为程序传递了Grandma的引用到 Mom的构造方法,Mom的双亲被设成是一个自定义的类装载器,指向Grandma。又过了一段时 间,程序创建了一个新的类装载器“Cind/’。因为应用程序传递了指向Mom的引用到Cindy的构 造方法,Cindy的双亲就被设定为用户自定义的Mom类装载器。

现在假设程序要求Cindy去装载一个名为java.io.FileReader的类型。当符合双亲委派模型的 类装载一个类型的时候,它首先委派它的双亲——请求它的双亲试着装载这个类型,它的双亲 再依次调用各自的双亲。这个委派的过程一直进行到委派链的末端,一般来说应该是启动类装 载器。因此,Cindy第一件事就是去找Mom来装载那个类型;Mom所做的第一件事就是去找Grandma来装载那个类型;而Grandma宵先是找启动类装载器去装载。在这个例子中,启动类装 载器可以装载(或者已经装载了)那个类型,它就返回代表java.io.FileReader的Class实例给 Grandma。Grandma传递该Class的引用回Mom, Mom再回传给Cindy,Cindy返回给程序。

请注意,在类装载器之间具有了委派关系,首先发起装载要求的类装载器不必是定义该类 型的装载器。在上面的例子中,程序首先要求Cindy去装载类型,但最终却是启动类装载器定义 了那个类型。在Java术语中,要求某个类装载器去装载一个类型,但是却返回了其他类装载器装 载的类型,这种装载器被称为是那个类型的初始类装载器;而实际定义那个类型的类装载器被 称为该类型的定义类装载器。因此在上一个例子中,java.io.FileReader定义类装载器是系统类装 载器。Cindy是初始类装载器,但是Mom、Grandma甚至系统类装载器也是初始类装载器。任何 被要求装载类型,并且能够返回Class实例的引用代表这个类型的类装载器,都是这个类型的初 始类装载器。

再比如,假设程序要求Cindy装载一个名为com.artima.knitting.QuihPattern的类型。Cindy委 派给Mom,Mom委派给Grandma,Grandma委派给系统类装载器。然而在这个例子中,系统类 装载无法装载这个类型,所以控制权回到Grandma, Grandma试阁去用自定义的方法去装载类型。 因为Grandma负责装载标准扩展,而com.artima.knitting包正确地以JAR文件格式被安装到了标准扩展目录,Grandma能够装载这个类型。Grandma定义了该类型,并返回了代表com.artima. knitting.QuiltPatteni的Class实例给Mom。Mom传递Class的引用给Cindy,Cindy返回给程序。在 这个例子中,Mom是com.artima.knittiug.QuiUPatteni类型的定义类装载器,Cindy、Mom和 Grandma一但是不包括启动类装载器——是该类型的初始类装载器。

原文地址:https://www.cnblogs.com/mongotea/p/11979579.html