①. 类的加载(掌握)
①. 简述类的加载过程(掌握)
- 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过
类的加载、类的链接、类的初始化
这三个步骤来对类进行初始化。 如果不出现意外,JVM将会连续完成这三个步骤,所以有时也把这三个步骤统称为类加载或者初始化
②. 什么是类的加载(Loading)
- 类的加载指的是将类的.class文件中的二进制数据读取到内存中,存放在运行时数据区的方法区中,并创建一个大的Java.lang.Class对象,用来封装方法区内的数据结构
③. 链接(Linking)
-
①. 验证:确保Class文件的字节流中包含信息符合当前虚拟机要求,保证被加载类的正确性
-
②. 准备:
- 为类变量分配内存并且设置该类变量的默认初始化值
- 不会为实例变量分配初始化
- ③. 解析:
(将常量池中的符号引号转换为直接引用的过程)
解释什么是符号引号和直接引用
教室里有个空的位子没坐人,座位上边牌子写着小明的座位(符号引用),后来小明进来坐下去掉牌子(符号引用换成直接引用)
④. 初始化(Initialization)
-
①. 为类变量赋予正确的初始化值
-
②. 初始化阶段就是执行类构造器方法< clinit >()的过程
-
③. 类的初始化阶段就是执行类的构造方法(clinit)的过程
(构造器方法中指令按语句在源文件中出现的顺序执行) -
④. < clinit > 不同于类的构造器,有静态变量或static{ } 代码块 那么字节码文件就有这个方法
-
⑤. 若该类具有父类,Jvm会保证子类的< clinit >() 执行前,父类的< clinit >() 已经执行完成
②. 类加载器的介绍
-
①. JVM支持两种类型的类加载器,分别为引导类加载器(Bootstrap ClassLoader)和自定义类加载器(User-Defined ClassLoader)
-
②. 从概念上来讲,自定义类加载器一般指的是程序中由开发人员自定义的一类类加载器,但是Java虚拟机规范并没有这么定义,而是将所有派生于抽象类ClassLoader的类加载器都划分为自定义类加载器
-
③. sum.misc.Launcher:它是一个java虚拟机的入口应用
-
④. 无论类加载器的类型如何划分,在程序中我们常见的类加载器始终只有3个,如下所示:
①. 启动类加载器
-
①. 这个类加载使用C/C++语言实现的,嵌套在JVM内部
-
②. 它用来加载Java的核心类库(JAVA_HOME/jre/lib/rt.jar、resource.jar或sum.boot.class.path路径下的内容),用于提供JVM自身需要的类
-
③. 并不继承自java.lang.ClassLoader,没有父加载器
-
④. 加载扩展类和应用程序类加载器,并指定为他们的父类加载器
-
⑤. 由于安全考虑,Bootstrap启动类加载器只加载包名为java、javax、sun等开头的类
②. 扩展类加载器(Extension ClassLoader)
-
①. Java语言编写,由sum.music.Launcher$ExtClassLoader实现
-
②. 派生于ClassLoader类
-
③.父类加载器为启动类加载器
-
④.从java.ext.dirs系统属性所指定的目录中加载类库,或从JDK的安装目录的jre/lib/ext子目录(扩展目录)下加载类库。如果用户创建的JAR放在此目录下,也贵自动由扩展类加载器加载
③. 应用程序类加载器(系统类加载器)
-
①. java语言编写,由sum.misc.Launcher$AppClassLoader实现
-
②. 派生于ClassLoader类
-
③. 父类加载器为扩展类加载器
-
④. 它负责加载环境变量classpath或系统属性java.class.path指定路径下的类库
-
⑤.
该类加载是程序中默认的类加载器
,一般来说,Java应用的类都是由它来完成加载 -
⑥. 通过ClassLoader#getSystemClassLoader()方法可以获取到该类加载器
④. 用户自定义类加载器(了解)
-
①. 在Java的日常应用程序开发中,类的加载几乎是由上述3种类加载器相互配合执行的,在必要时,我们换可以自定义类加载器,来定制类的加载方式
-
②. 如果获取ClassLoader
⑤. 双亲委派机制 (掌握)
- ①. 工作原理
- ②. 优势:
⑥. 沙箱安全机制 (掌握)
⑦. 如何判断两个Class对象是否相同
- ①. 相同必须的两个条件如下:
- ②. JVM必须知道一个类型是由启动加载器加载还是用户类加载器加载的。如果一个类型是又用户类加载器加载的,
那么JVM会将这个类加载器的一个引用作为类型信息的一部分保存在方法区中。