1.Java语言的类型
Java语言的类型分为基本类型和引用类型。基本类型包括:byte、short、int、long、float、double、boolean、char。引用类型包括:类、接口、数组类、泛型参数,其中泛型参数在编译阶段会被清除,所以在java虚拟机中运行的时候只有类、接口和数组类三种引用类型。
2.类的生命周期
虚拟机加载类的过程主要分为:加载、连接、初始化三个阶段,其中连接阶段可以细分为验证、准备、解析三个步骤。
类完整的生命周期如下:
加载->连接(验证、准备、解析)->初始化->使用->卸载
3.加载
3.1 加载的定义
查找字节流,据此创建类的过程。由于数组类没有对应的字节流,而是有由虚拟机直接创建的,故对于数组类来说是没有加载这一阶段的。对于其他类来说需要借助类加载器来完成字节流的查找。
3.2.类加载器
类加载器必须首先由其他类加载器先加载到虚拟机中才能开始加载类。
Java中有四种类加载器:启动类加载器、扩展类加载器/平台类加载器、应用类加载器、自定义加载器,其中前三种类加载器由Java核心类库提供。
启动类加载器由C++实现,没有对应的java对象,其他类加载器都是java.lang.classloader的子类。在JDK9之前,启动类加载器加载最基础、最重要的类,比如存放在JRE的lib目录下的jar包及通过虚拟机参数-Xbootclasspath指定的类。
扩展类加载器的父类是启动类加载器,加载JRE的lib/ext目录下的Jar包及通过系统变量java.ext.dirs指定的类。
应用类加载器的父类是扩展类加载器,负责加载应用程序路径下的类,即虚拟机参数-cp/-classpath、系统变量java.class.path或环境变量CLASSPATH所指定的路径。
Java9引入了模块系统,扩展类加载器改名为平台类加载器,除了java.base由系统类加载加载外,其他模块均由平台类加载器加载。
可以自定义加载器来实现特殊的类加载功能,比如字节码文件的加解密。
3.3.类的唯一性
Java中类的唯一性由类加载实例及类的全名一同确定。所以不同的类加载器加载相同的字节码会得到不同的类。
4.连接
将创建的类合并到虚拟机中使之能够执行。
连接阶段分为:校验、准备、解析;准备阶段为类的静态字段分配内存(注意具体的初始化在初始化阶段进行);
解析阶段讲符号引用解析为实际应用。
Java虚拟机规范不要求在连接阶段完成解析,只要求在执行字节码之前完成符号应用的解析。
5.初始化
初始化干些什么事情?
为标记为常量值的字段赋值及执行<clinit>方法,虚拟机会通过加锁来确保类的<clinit>方法仅被执行一次。
有且仅有的类的初始化触发时机
(1)new、访问静态字段或者方法
(2)反射调用类
(3)初始化一个子类时如果父类没有初始化,要先初始化父类;
(4)启动虚拟机的主类;
注意:类的初始化只会被执行一次