Java静态变量的初始化分析

首先解释下:
static关键字修饰变量
表示该类的所有对象共同拥有该属性,相当于该类的全局变量,类变量在加载的时候就初始化,而且只被初始化一次,程序中任何该类的对象对类变量做修改的时候,该类的其他对象得到的是修改之后的值,因此类量可以作为计数器,而且static变量可以用类名直接访问不需要创建对象之后再访问。
static修饰代码块
static修饰类里面独立的代码块,称为静态代码块,静态代码块在第一次的时候执行,而且执行一次,由于静态代码块没有名字,所以不能显示的调用,只有在类加载的时候有虚拟机去调用,主要完成一些初始化的操作。
static修饰方法
static修饰方法时,意味着所有对象拥有同一方法,static修饰的方法也是可以直接通过类名去调用,所以在静态变量里不能直接访问非静态对象和非静态方法,在静态方法中不能出现this,super等关键字。
类的加载:
在jvm第一次使用一个类的时候,会通过查找classpath所指定的路径,找到该类所对应的字节码,然后加载到jvm中保存起来,这个过程就称为类加载。
无论是static修饰的变量,方法,还是代码块,类被加载之后就可以执行,都可以脱离对象执行,不用通过对象创建,用对象去执行。

java代码:Order.class

public class Order {
    static Shirt s1 = new Shirt();
    static Pants p2;
    Boot t3 = new Boot(10);

    void print() {
        t3.fun();
    }

    public static void main(String[] args) {
        System.out.println("Creating new Shirt() in main");
        new Shirt();
        System.out.println("Creating new Shirt() in main");
        Order od = new Order();
        od.t3.fun();
        Pants t4 = new Pants("aa", 1);
    }
}

java代码:Boot.class

public class Boot {
    Boot(int marker) {
        System.out.println("Boot(" + marker + ")");
    }

    void fun() {
        System.out.println("BootfunOk");
    }
}

java代码:Pants.class

public class Pants {
    Pants() {
        System.out.println("Pants()");
    }

    Pants(String a, int i) {
        this();
        System.out.println("PantsOk");
    }
}

java代码:Shirt.class

public class Shirt {
    Boot b1 = new Boot(1);
    /** 先static后非static变量初始化的顺序原则开始初始化各个变量. */
    static Boot b2 = new Boot(2);

    Shirt() {
        System.out.println("Shirt()");
    }

    static Boot b3 = new Boot(3);
}

分析运行结果:
首先从public类开始运行,这时候会加载Order.class,
1,先运行 static Shirt s1 = new Shirt();
由于s1是一个对象的引用变量,首先会得到初始化,就会跳到Shirt的实例中按照先static后非static的变量初始化的顺序开始初始化各个变量,
1.1,
在Shirt中顺序:
静态变量
static Boot b2 = new Boot(2);
static Boot b3 = new Boot(3);
非静态变量
Boot b1 = new Boot(1);
变量初始化完成之后再执行Shirt的构造方法
1.2,
Shirt() {
System.out.println(“Shirt()”);
}
Shirt s1初始化完成之后再回到public类Order.class中
2,这是有static Pants p2;
由于p2只是声明变量没有创建对象让它指向,因此接着执行下面的操作
3,发现static变量都初始化完成,那么程序就转如static方法中执行,也就是执行static的main方法,输出:System.out.println(“Creating new Shirt() in main”);
注意:(Boot t3 = new Boot(10); 这一句为什么得不到初始化,是因为此时没有创建类Order的实例,所以程序目前还不会初始化该代码,至于以后会不会初始化,还要看在main方法中是否会创建Order类的实例,如创建了,则一定初始化,否则不会.)
4,接着就执行new Shirt();,也就是创建一个Shirt对象, **注意:**static变量的初始化,它只能初始化一次,也就是说,如果前面已经初始化过了,那么此时就不必要再初始化了.
4.1,也就只会初始化非静态变量 Boot b1 = new Boot(1);
4.2,变量初始化完成之后就执行构造方法
Shirt() {
System.out.println(“Shirt()”);
}
5,再回到main 方法中 输出 System.out.println(“Creating new Shirt() in main”);
6,接着执行mian方法中的下一步Order od = new Order();
还是由于static变量的初始化,它只能初始化一次,所以创建Order对象时就只执行初始化非静态变量 , 也就是创建非静态对象 Boot t3 = new Boot(10);
7,接着执行mian方法,调用od.t3.fun();
8,最后执行main方法中的最后一句 Pants t4 = new Pants(“aa”, 1);
8.1,执行pants的两个参数的构造方法时,会调用this(),所以依然会调用无参数的构造方法,所以先执行无参数的构造。
Pants() {
System.out.println(“Pants()”);
}
8.2,然后再是两个参数的构造方法
Pants(String a, int i) {
System.out.println(“PantsOk”);
}

运行输出结果是:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值