• java关键字static使用的“坑”(准备、初始化)


    一、引入

    类的生命周期

    包括以下 7 个阶段:

    • 加载(Loading)

    • 验证(Verification)

    • 准备(Preparation)

    • 解析(Resolution)

    • 初始化(Initialization)

    • 使用(Using)

    • 卸载(Unloading)

    类加载过程

    包含了加载、验证、准备、解析和初始化这 5 个阶段。(详细参看其他博客)

    准备阶段:

    类变量是被 static 修饰的变量,准备阶段为类变量分配内存并设置初始值,使用的是方法区的内存。
    
    全局变量(成员变量,可能也会被人被称为实例变量):比如在类的方法外定义的变量public int cnt=1;是全局变量或者叫做字段。
    
      1.全局变量既不在堆中,也不在栈中,而是在全局区(静态区)全局变量的存储和静态变量是在一起的。(有点蒙,为什么这么说,静态区难道不是属于方法区?可能是分得更细)
    
      2.初始化的全局变量和静态变量在同一块区域“数据段”;未初始化的全局变量和静态变量在相邻的另一块区域“数据段中的BSS段:特点是可读可写;在程序执行前BSS段会清0”
    
    实例变量不会在这阶段分配内存,它会在对象实例化时随着对象一起被分配在中。应该注意到,实例化不是类加载的一个过程,类加载发生在所有实例化操作之前,并且类加载只进行一次,实例化可以进行多次。

    准备阶段初始值一般为 0 值,例如下面的类变量 value 被初始化为 0 而不是 123。

    public static int value = 123;

    如果类变量是常量,那么它将初始化为表达式所定义的值而不是 0。例如下面的常量 value 被初始化为 123 而不是 0。

    public static final int value = 123;

    初始化

    二、这是由于类加载过程的准备阶段+初始化阶段导致的“坑(结果)”:

    问题产生:static Main2 m = new Main2();与public static int cnt=1;声明的先后位置导致的

    /**
    1. 因为static Main2 m = new Main2();用了static修饰,所以类初始化的时候,会执行一次构造方法
    2. 因为static Main2 m = new Main2();是写在public static int cnt=1;之后的,所以syso将会输出cnt=2
    **/
    public class Main2 {
        public static int cnt=1;
        static Main2 m = new Main2();
        public Main2(){
            cnt++;
            System.out.println("	cnt="+cnt);
        }
        public static void main(String[] args) {}
    }
    //输出cnt=2
    /**
    静态字段的初始化规则为:1.首先默认初始化为0,null等等;然后再显示初始化。
    所以显示初始化m=new Main2()的之前,cnt=0;然后再执行构造函数,其中cnt++使cnt的值变为1;然后再显示初始化cnt=1,所以syso输出cnt=1
    **/
    public class Main2 {
        static Main2 m = new Main2();
        public static int cnt=1;
        public Main2(){
            cnt++;
            System.out.println("	cnt="+cnt);
        }
        public static void main(String[] args) {}
    }
    //输出cnt=1
  • 相关阅读:
    3月6日
    2月28日
    2月23日
    2月20日
    2月19日
    2月18日
    2月17日
    2月16日
    2月15日
    面试算法题——硬币找零
  • 原文地址:https://www.cnblogs.com/sunupo/p/13591055.html
Copyright © 2020-2023  润新知