海牛部落 java 系列教程:(16) 类加载机制与反射

教程 青牛 ⋅ 于 2017-09-20 14:17:37 ⋅ 最后回复由 stt824726 2018-10-09 09:22:40 ⋅ 8012 阅读

1 类加载机制

1.1 类的生命周期

file

1.1.1 类的加载
类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构。类的加载的最终产品是位于堆区中的Class对象,Class对象封装了类在方法区内的数据结构,并且向Java程序员提供了访问方法区内的数据结构的接口。

file

JAVA的JVM的内存可分为3个区:堆(heap)、栈(stack)和方法区(method)
堆区:
1)存储的全部是对象,每个对象都包含一个与之对应的class的信息。(class的目的是得到操作指令)
2)jvm只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身
栈区:
1)每个线程包含一个栈区,栈中只保存基础数据类型的对象和自定义对象的引用(不是对象),对象都存放在堆区中 。
2)每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问。
3)栈分为3个部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)。
方法区:
1)又叫静态区,跟堆一样,被所有的线程共享。方法区包含所有的class和static变量。
2)方法区中包含的都是在整个程序中永远唯一的元素,如class,static变量。

   类加载器并不需要等到某个类被“首次主动使用”时再加载它,JVM规范允许类加载器在预料某个类将要被使用时就预先加载它,如果在预先加载的过程中遇到了.class文件缺失或存在错误,类加载器必须在程序首次主动使用该类时才报告错误(LinkageError错误)如果这个类一直没有被程序主动使用,那么类加载器就不会报告错误。

加载.class文件的方式
– 从本地系统中直接加载
– 通过网络下载.class文件
– 从zip,jar等归档文件中加载.class文件,如:JDBC加载数据库驱动。
– 从专有数据库中提取.class文件
– 将Java源文件动态编译为.class文件
1.1.2 类的连接
类连接分为3个阶段:
验证:确保被加载的类的正确性。
准备:为类的静态变量分配内存,并将其初始化为默认值。

file

解析:把类的二进制数据中的符号引用转换为直接引用。
1.1.3 类的初始化
初始化,为类的静态变量赋予正确的初始值,JVM负责对类进行初始化,主要对类变量进行初始化。
1.1.3.1 在Java中对类变量进行初始值设定有两种方式
static 修饰的成员变量
声明类变量是指定初始值

使用静态代码块为类变量指定初始值

file

1.1.3.2 JVM初始化步骤
假如这个类还没有被加载和连接,则程序先加载并连接该类

假如该类的直接父类还没有被初始化,则先初始化其直接父类

假如类中有初始化语句,则系统依次执行这些初始化语句

然后系统对直接父类的初始化步骤也遵循1~3步。
1.1.3.3 类初始化时机
只有当对类的主动使用的时候才会导致类的初始化。
类的主动使用包括以下六种:
创建类的实例。
1)使用new造作创建实例。
2)通过反射来创建实例。
3)通过反序列化的方式来创建实例。
访问某个类或接口的静态属性,或者对该静态属性赋值

调用类的静态方法

反射(如Class.forName(“com.shengsiyuan.Test”))

初始化某个类的子类,则其父类也会被初始化

Java虚拟机启动时被标明为启动类的类(Java Test),直接使用java.exe命令来运行某个主类

1.1.4 结束生命周期
在如下几种情况下,Java虚拟机将结束生命周期
执行了System.exit()方法

程序正常执行结束

程序在执行过程中遇到了异常或错误而异常终止

由于操作系统出现错误而导致Java虚拟机进程终止

1.2 类加载器
1.2.1 三种系统提供的类加载器
启动类加载器(Bootstrap ClassLoader):
  也称引导类加载器,负责将\lib目录下的类库加载到虚拟机内存中,用来加载java的核心库,此类加载器并不继承于java.lang.ClassLoader,不能被java程序直接调用。
扩展类加载器(Extendsion ClassLoader):
  这个类加载器负责加载\lib\ext目录下的类库,用来加载java的扩展库,开发者可以直接使用这个类加载器。
应用程序类加载器(Application ClassLoader):
  这个类加载器负责加载用户类路径(CLASSPATH)下的类库,一般我们编写的java类都是由这个类加载器加载,这个类加载器是CLassLoader中的getSystemClassLoader()方法的返回值,所以也称为系统类加载器。一般情况下这就是系统默认的类加载器。
  除此之外,我们还可以加入自己定义的类加载器,以满足特殊的需求,需要继承java.lang.ClassLoader类。

file

file

需要注意的是这里并没有输出引导类加载器,这是由于有些 JDK 的实现对于父类加载器是引导类加载器的情况,getParent()方法返回 null。
1.2.2 类加载机制
全盘负责:

回复帖子,然后刷新页面即可查看隐藏内容

版权声明:原创作品,允许转载,转载时务必以超链接的形式表明出处和作者信息。否则将追究法律责任。来自海汼部落-青牛,http://hainiubl.com/topics/164
本帖由 海牛部落 于 6年前 取消置顶
点赞
成为第一个点赞的人吧 :bowtie:
回复数量: 22
暂无评论~~
  • 请注意单词拼写,以及中英文排版,参考此页
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`, 更多语法请见这里 Markdown 语法
  • 支持表情,可用Emoji的自动补全, 在输入的时候只需要 ":" 就可以自动提示了 :metal: :point_right: 表情列表 :star: :sparkles:
  • 上传图片, 支持拖拽和剪切板黏贴上传, 格式限制 - jpg, png, gif,教程
  • 发布框支持本地存储功能,会在内容变更时保存,「提交」按钮点击时清空
Ctrl+Enter