与那些编译时需要进行连接的语言不同,在java语言中,类型的
动态加载:编写一个面向接口的应用程序,可以等到运行时再指定其实现类。
类加载:加载-连接-初始化-使用-卸载
一个类被调用时,会将其class文件从磁盘中加载到虚拟机中。
加载
(1)通过一个类的全限定名来获取定义此类的二进制字节流。
(2)将这个流转换为方法区的静态文件结构。
(3)在内存中生成Class对象,作为方法区的访问入口。
连接的过程
先验证class文件的安全性,然后开辟类变量的空间和位置,将常量池中的符号引用替换为直接引用。
初始化
初始化阶段就是执行类构造器()方法的过程。
()是javac编译器自动生成的产物。
()是类中的所有类变量的赋值当作和静态static块语句合并产生的,按照程序顺序生成。
类加载器
根据类的全限定名获取所需要的类。
对于任意一个类,都必须由加载它的类加载器和这个类本身一起确认其唯一性。对于每一个类加载器,都有一个独立的类名称空间。这里的唯一性,体现在equals()方法,isInstance()方法。
启动类加载器:加载<java_home>/lib目录的java核心类
扩展类加载器:加载<java_home>/lib/ext目录下的类库
应用程序类加载器:是ClassLoader.getSystemClassLoader()方法的返回值,加载用户路径上的类,即用户自己写的类
双亲委派:如果一个类加载器加载类,会先委派给启动类加载器,然后是扩展类加载器,发现类不在其加载路径上,才会由应用类加载器加载
Tomcat:正统的类加载机制
web服务器需要解决以下问题:
- 部署在一个tomcat上的应用程序java类库可以互相隔离
- 部署在同一个tomcat上的两个应用程序使用的java类库可以相互共享
- 服务器的类库和应用程序的类库互相独立
这样,一个classpath的类加载器就无法解决了。
应用类加载器是负责加载应用程序类路径(classpath)上定义的类的类加载器。
所以需要将不同应用的类库放在不同的路径上,用不同的类加载器加载。
tomcat定义了多个类加载器,这些类加载器按照经典的双亲委派模型来实现。
字节码生成技术和动态代理的实现
最基础的,javac生成class文件就是字节码生成。
动态代理:spring的bean的aop,或者class的Proxy或者代理接口,