前言
做Java开发将近一年半了,虽然之前系统地学习过Java,但是实践出真知,最近总感觉还有好多知识点没有掌握,尤其是看大神写的代码,经常会还有如此操作的感叹。于是又沿着《Java核心编程技术卷一》这本书重新学习下Java,读了一部分,发现学习了到了很多,以前不太理解的东西也瞬间懂了。一些自己感觉容易忘记,或者不太好理解的知识点,记下来以备后用。
类初始化的条件
我们知道类从被加载到虚拟机内存中开始,到卸载出内存中为止,它的整个生命周期包括:加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸载(Unloading)7个阶段。这7个阶段的发生顺序如下图所示。

对于类初始化来说,JVM规范严格规定了有且只有5中情况必须立即对类进行初始化。
1) 使用new关键字实例化对象的时候、 读取或设置一个类的静态字段(被final修饰、已在编译器把结果放入常量池的静态字段除外)的时候、调用一个类的静态方法的时候的时候。
2) 使用java.lang.reflect包的方法对类进行反射调用的时候,如果类没有进行过初始化,则需要先触发其初始化。
3) 初始化子类时,先对其父类进行初始化。
4) 虚拟机启动时,先初始化主类(包含main()方法的那个类)
5) 看不懂这一条,略过
初始化顺序
package com.resum.javabase;
import java.util.Random;
public class ConstructorTest {
public static void main(String[] args) {
Manager manager = new Manager("laozhang", 15000);
double salary = manager.getSalary();
System.out.println(salary);
}
}
class Employee {
private static int nextId;
private int id;
private String name = "";//5
private double salary;
public static final String address = "Shanghai";
static {//1
Random rand = new Random();
nextId = rand.nextInt(1000);
}
{//6
id = nextId;
nextId++;
salary = 8000;
}
public Employee(String name, double salary) {//4
this.name = name;//7
this.salary = salary;
}
public Employee(double salary) {
this("Employee#" + nextId, salary);
}
public Employee() {//3
}//6
public String getName() {
return this.name;
}
public double getSalary() {
return this.salary;
}
public int getId() {
return this.id;
}
}
class Manager extends Employee {
private double bonus;
public static String ip;
public static final String address = "BeiJing";
static {
ip = "192.168.0.0.1";//2
}
{
bonus = 100;//8
}
public Manager(String name, double salary) {
super(name, salary);//3
}//9
public double getSalary() {
return super.getSalary() + this.bonus;
}
}
总结
非继承关系类初始化顺序
静态成员和static块->普通成员和非static块->构造函数
继承关系类初始化顺序
父类静态成员和static块->子类静态成员和static块->父类普通成员和非static块->父类构造函数->子类普通成员和非static块->子类构造函数
网友评论