1.Class文件
Java class文件是对Java程序二进制文件格式的精确定义,每一个java class文件都对一个类或者一个接口作出了全面的描述。当每一次使用类时,JVM会检查对应的class文件是否已经加载,如果未加载,则需要通过类加载子系统来加载。类加载的过程如下:
(1)装载-----查找并装载类型的二进制数据,即读取.class文件。
(2)连接-----执行验证准备以及解析。
验证:确保被导入类型的正确性;
准备:为类变量分配内存,并将其初始化为默认的值;
解析:把类型中的符号引用转化为直接引用;
若正在被加载的类还有父类,且父类没有被加载,则对其所有父类(未加载的)执行步骤1和步骤2,加载顺序为从直接基类到最上层的父类依次执行装载和连接。
(3)初始化-----将类变量初始化为正确的初始值。对所有未加载的父类,从最上层的父类开始依次往下到最该类,执行静态初始化和静态初始化块。
在生成实例对象的时候,首先给实例变量分配相应的内存,也会为其父类中定义的所有实例变量分配内存,对所有父类(从上到下)执行非静态初始化块,构造器。依次调用完成以后,才执行本类的非静态初始化块和构造函数。
2.final变量
当定义final变量为就为该变量指定了初始值,而且该初始值可以在编译时就确定下来,那么这个final变量本质上就是一个“宏变量”,编译器会把程序中所有用到该变量的地方都直接替换成该变量的值。
3.字符串字面值
Java会缓存使用过的字符串,把字符串的字面常量都放在了字符串驻留池中。
String a="java";
String b="java";
上面的代码中,首先定义了一个字符串对象a,由于“java’是一个字符串的字面常量,因此会缓存到字符串缓存池中。当运行到第二句时,编译器不会创建两一个字符串对象,而是直接将引用变量b指向字符串缓冲池中的常量“java"。此时,a和b其实引用的是同一个字符串对象。执行以下语句将返回true。
System.out.println(a==b); //true