疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

类的加载、连接和初始化—[疯狂java讲义]


 

        本章将会深入介绍Java类的加载、连接和初始化的深入知识,并重点介绍Java反射相关的内容。读者在阅读本章的类加载、连接及初始化知识时,可能会感觉这些知识比较底层,但掌握这些底层的运行原理会让读者对Java程序的运行有更好的把握。而且Java类加载器除了根类加载器之外,其他类加载器都是使用Java语言编写的,所以程序员完全可以开发自己的类加载器,通过使用自定义类加载器,可以完成一些特定的功能。
 
        本章重点将深入介绍java.lang.reflect包下的接口和类,包括Class、Method、Field、Constructor和Array等,这些类分别代表方法属性构造器数组,Java程序可以使用这些类动态地获取某个对象、某个类的运行时信息,并可以动态地创建Java对象,动态地调用Java方法,访问并修改指定对象的属性值。本章还将介绍该包下的Type和ParameterizedType两个接口,其中Type是Class类所实现的接口,而ParameterizedType则代表一个带泛型参数的类型。
 
        除此之外,本章还将介绍使用Proxy和InvocationHandler来创建JDK动态代理,并会通过JDK动态代理向读者介绍高层次解耦的方法,还会讲解JDK动态代理和AOP (Aspect Orient Programming,面向切面编程)之间的内在关系。
 
        系统可能在第一次使用某个类时加载该类,也可能采用预先加载机制来预加载某个类,本节将会详细介绍类加载、连接和初始化过程中的每个细节。
 
JVM和类
 
       当我们调用Java命令运行某个Java程序时,该命令将会启动一条Java虚拟机进程,不管该Java程序有多么复杂,该程序启动了多少个线程,它们都处于该Java虚拟机进程里。正如前面介绍的,同一个JVM的所有线程、所有变量都处于同一个进程里,它们都使用该JVM进程的内存区。当系统出现以下几种情况时,JVM进程将被终止:
 
1、程序运行到最后正常结束。
2、程序运行到使用System.exit()或Runtime.getRuntime().exit()代码结束程序。
3、程序执行过程中遇到未捕获的异常或错误而结束。
3、程序所在平台强制结束了JVM进程。
从上面的介绍可以看出,当Java程序运行结束时,JVM进程结束,该进程在内存中状态将会丢失。
 
类的加载
 
         当程序主动使用某个类时,如果该类还未被加载到内存中,系统会通过加载、连接、初始化三个步骤来对该类进行初始化,如果没有意外,JVM将会连续完成这三个步骤,所以有时也把这三个步骤统称为类加载或类初始化。
 
        类加载指的是将类的class文件读入内存,并为之创建一个java.lang.Class对象,也就是说当程序中使用任何类时,系统都会为之建立一个java.lang.Class对象。
 
        前面我们介绍面向对象时提到:类是某一类对象的抽象,类是概念层次的东西.但不知道读者有没有想过:类也是一种对象。就像我们说概念主要用于定义、描述其他事物,但概念本身也是一种事物,那么概念本身也需要被描述,这有点像一个哲学命题。但事实就是这样,每个类是一批具有相同特征的对象的抽象(或者说概念),而系统中所有的类,它们实际上也是对象,它们都是java.lang.Class的实例。
 
        加载由类加载器完成,类加载器通常由JVM提供,这些类加载器也是我们前面所有程序运行的基础,JVM提供的这些类加载器通常被称为系统类加载器。除此之外,开发者可以通过继承ClassLoader基类来创建自己的类加载器。
 
通过使用不同的类加载器,可以从不同来源加载类的二进制数据,通常有如下几种来源:
 
1、从本地文件系统来加载class文件,这是前面绝大部分示例程序的类加载方式。
2、从JAR包中加载class文件,这种方式也是很常见的,前面介绍JDBC编程时用到的数据库驱动类就是放在JAR文件中,JVM可以从JAR文件中直接加载该class文件。
3、通过网络加载class文件。
4、把一个Java源文件动态编译、并执行加载。
 
类加载器通常无须等到“首次使用”该类时才加载该类,Java虚拟机规范允许系统预先加载某些类。摘自:《疯狂java讲义》