`

Java学习 之 类加载和反射

阅读更多

1.类的加载,连接和初始化

 

 1.1 JVM和类

 同一个JVM的所有线程,所有变量都处于同一个进程里,它们都使用该JVM进程的内存区,当系统出现一下情况,JVM进程将被终止:

  1.1.1 程序运行到最后正常结束;

  1.1.2 程序运行到System.exit()或Runtime.getRuntime().exit()代码结束程序;

  1.1.3 程序运行过程中遇到了未捕获的异常或错误而结束;

  1.1.4 程序所在平台强制结束了JVM进程。

 当Java程序运行结束时,JVM进程结束,该进程在内存中状态将会丢失。

 

 1.2 类的加载

 当程序主动使用某个类时,如果该类未被加载到内存中,系统会通过加载、连接、初始化三个步骤来对该类进行初始化,统称为类加载或类初始化。

 类加载指的是将类的class文件读入内存,并为之创建一个java.lang.Class对象,也就是说当程序中使用任何类时,系统都会为之创建一个java.lang.Class对象。

 系统中所有的类,它们实际上也是对象,它们都是java.lang.Class的实例。

 

 1.3 类的连接

 类的连接阶段负责把类的二进制数据合并到JRE中,可分为三个阶段:

  1.3.1 验证:用于检验被加载的类是否有正确的内部结构,并和其他类协调一致;

  1.3.2 负责:为类的静态属性分配内存,并设置默认初始值;

  1.3.3 解析:将类的二进制数据中的符号引用替换成直接引用。

 

 1.4 类的初始化

 主要就是对静态属性进行初始化,在Java类中对静态属性指定初始值有两种方式:

  1.4.1 声明静态属性时指定初始值;

  1.4.2 使用静态初始化块为静态属性指定初始值。

 类的初始化一般包括一下几个步骤:

  1.4.1 若该类未被加载和连接,程序先加载并连接该类;

  1.4.2 若该类的直接父类未被初始化,则先初始化其直接父类;

  1.4.3 若该类中有初始化语句,则系统依次执行这些初始化语句。

 因此,我们可以推算出,JVM最先初始化的总是java.lang.Object类。当任何一个类被系统使用时,系统会保证该类及所有父类都会被初始化。

 

 1.5 类初始化的时机

 当程序首次通过下面6种方式类使用某个类或接口时,系统就会初始化该类或接口;

  1.5.1 创建该类的实例。为某个类创建实例的方式包括:

   (1)new操作符来创建实例;

   (2)通过反射来创建实例;

   (3)通过反序列化的方式类创建实例。

  1.5.2 调用某个类的静态方法;

  1.5.3 访问某个类或接口的静态属性,或为该静态属性赋值;

  1.5.4 使用反射方式来强制创建某个类或接口对应的Class对象。如:Class.forName("Person");,如果系统为初始化Person类,则会导致该Person类初始化并返回Person类对应的Class对象。

  1.5.5 初始化某个类的子类,当初始化某个类的子类时,该子类的所有父类都会被初始化。

  1.5.6 直接使用java.exe命令来运行某个筑垒,当运行某个主类时,程序会先初始化该主类。

  另外需要注意一下2点:(1)对于一个final类型的静态属性,如果该属性可以在编译时就得到属性值,则可认为该属性可被当成编译时常量。当程序使用该编译时常量时,系统会认为这是对该类的被动使用,所以不会导致该类的初始化。即相当于使用一个常量。(2)使用ClassLoader类的loadClass方法来加载某个类时,该方法只是加载该类,并不会执行类的初始化。使用Class的forName静态方法才会导致强制初始化该类。

 

 。。。 。。。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics