static 关键字


工作中static用处非常多修饰变量,方法等等

static

1.修饰常量项目中常用于静态常量

private static final short LOCAL_DATE_FORMAT_SLASH = 14;

2.修饰方法,静态方法,长用于工具类中

public class HutoolDateUtil {
    /**
     * 获取全年(年月份)
     * @return
     */
    public static List creatMonthOfYearDate(){...}
}

3.静态内部类,实际很少用

public class TestNum {
    
    static class Num{
        void test(){
            System.out.println("静态内部类");
        }
    }
}

4.修饰代码块

public class TestNum {

    static {
        System.out.println("这是代码块");
    }
}

static进阶


java栈也称作虚拟机栈(Java Vitual Machine Stack):java栈是线程私有的数据区,java栈的生命周期和线程相同,局部变量存储位置,方法的执行过程会创建浅帧(stack frame)
堆:堆是线程共享的数据区,堆是JVM中存储最大的一块区域,其中所有对象的实例,实例的变量都在堆中。
本地方法栈:本地方法栈是线程私有的数据区,java中navive关键字修饰的方法存储区域。
程序计数器:程序计数器是线程私有的数据区,用于存在线程指令地址,用于判断的分支,循环,跳转,异常,线程的切换和恢复功能,这些都是程序计数器来完成。
方法区:方法区是线程共享的内存区域,用于虚拟机加载类信息、常量、静态变量、即时编译后的代码等数据,static修饰的变量存储在方法区中。

static 序列化

序列化的目的是把java对象转为字节序列,对象转化为有序字节流,用于网络传输存储。
static和transient声明的变量不能被序列化,因为static修饰的变量存储在方法区中,只有堆内存中的才会被序列化,transient关键字作用是防止对象被序列化。

类加载顺序

我们前面提到了类加载顺序这么一个概念,static 修饰的变量和静态代码块在使用前已经被初始化好了,类的初始化顺序依次是
加载父类的静态字段 -> 父类的静态代码块 -> 子类静态字段 -> 子类静态代码块 -> 父类成员变量(非静态字段)
-> 父类非静态代码块 -> 父类构造器 -> 子类成员变量 -> 子类非静态代码块 -> 子类构造器