Java连接模型允许用户自行定义类装载器,这样一来就可以在运行时定制地扩展用户的程序。通过用户自定义的类装载器,你的程序可以装载在编译时并不知道或许尚未存在的类或者接口,并动态连接他们。
1.动态连接和解析
当编译Java程序的时候,会得到程序中每一个类或者接口的独立的class文件。虽然独立看上去毫无关联,但是他们之间通过接口符号互相联系,或者与Java API的class文件相联系。
class把他们所有的引用符号放在一个地方——常量池。每一个class文件有一个常量池,每一个被Java虚拟机装载的类或者接口都有一份内部版本常量池,被称作运行时常量池。运行时常量池是特定与实现的数据结构,数据结构映射到class文件中的常量池。因此,当一个类型被首次装载的时候,所有来自于类型的符号引用都装载到了类型的运行时常量池。
在程序运行的过程中,如果某个特定的符号引用将要被使用,它首先要被解析。解析过程就是首先根据符号引用查找到实体,再把符号引用替换成直接引用的过程。因为所有的符号引用都是保存在常量池中,所以这种解析叫做常量池解析。
连接不仅仅包括把符号引用替换成直接引用,还包括检查正确性和权限。
1.1解析和动态扩展
Java体系允许程序动态的扩展Java程序,这个过程包括运行时决定所使用的类型,装载它们,使用它们。通过传递类型的名字到java.lang.Class的forName()方法,或者用户自定义的类装载器的loadClass()方法,可以动态扩展Java程序。
public static Class forName(String className,boolean initialize,ClassLoader loader) throws ClassNotFoundException;
如果initialize为true,则在forName方法返回前会对类型进行装载,连接,初始化,如果为false,类型会被装载,可能会被连接,但不会被初始化。loader传递一个用户定制的类装载器的引用给forName(),让其使用这个类装载器来请求类型。
动态扩展java程序的另外一种方式就是使用用户自定义类装载器的loadClass()方法,如果需要用自定义的类装载器请求类型,只需要调用那个类装载器的loadClass()方法。
如果要求装载完成就初始化的话用forName()方法。如果安全要求的话用loadClass(),因为它们有不同的命名空间。
1.2类装载器和双亲委派模型
1.3常量池解析
1.4