我拿一个代码给你当例子讲解吧
- public class TestStatic {
- /**
- * main方法执行前会有很多事可干
- */
- //静态代码块会随着.class字节码文件加载入内存而加载,所以静态代码块执行一次
- //静态代码块和静态属性谁先执行,取决于谁在程序代码的上面
- //执行静态属性这行代码创建对象,调用构造方法,必须先加载对象的字节码文件,程序执行到36行
- static AllPerson p1 = new AllPerson();
- static {
- //静态代码块执行完后,执行main()函数
- System.out.println("TestStatic静态代码块执行");
- }
- public static void main(String[] args) {
-
- System.out.println("main函数现在才开始得到执行");
- }
- }
- class AllAnimal {
- static {
- //执行下面这行代码后,代表该类字节码文件已经加载进内存了,然后再加载子类字节码文件,又重新跳回33行
- System.out.println("AllAnimal静态代码块执行");
- }
- //父类构造方法执行完成后,子类中的静态属性加载完毕,调用子类的构造方法,子类的构造方法又会调用父类的工作方法
- //所以会出现AllAnimal构造方法执行连续出现两行的情况,程序跳到46行
- public AllAnimal() {
- System.out.println("AllAnimal构造方法执行");
- }
- }
- class AllPerson extends AllAnimal{
- static {
- //此时执行静态代码块吗,错,有父类的话,先加载父类字节码文件,执行父类静态代码块和静态属性,和构造方法类似
- //程序跳到22行
- System.out.println("AllPerson静态代码块执行");
- //这句代码执行完后,代表所需要的字节码文件全部加载进内存,这时加载后面的静态属性后就可以执行构造方法
- }
- //创建父类对象,因为父类中的静态代码块只执行一次,所以直接调用父类构造方法,程序跳到26行
- static AllAnimal aa = new AllAnimal();
- public AllPerson() {
- //执行到这行会直接调用构造方法中的内容吗,不是,执行之前得加载字节码文件,由类加载器去加载,
- //随着类加载器的载入,静态属性和静态代码块又得到执行,程序跳到32行
- System.out.println("AllPerson构造方法执行");
- //构造方法执行完后,程序跳转到11行
- }
- }
复制代码 仔细看我的注释
创建对象需要该对象的字节码文件,此时就必须加载字节码文件,由类加载器去加载,不懂可以去看张老师的高新技术视频,如果该类有父类,就必须先加载父类的字节码文件,加载完最终父类后加载子类字节码文件,不管是静态方法还是非静态方法,你不调用,就得不到运行,静态代码块通过类名调用。非静态代码块通过对象调用 |