关于 Java 类加载初始化

问:简单说说下面程序的运行结果?
        public class Base {
            public static int s;
            private int a;

            static {
                System.out.println("基类静态代码块, s:" + s);
                s = 1;
            }

            {
                System.out.println("基类实例代码块, a:" + a);
                a = 1;
            }

            public Base() {
                System.out.println("基类构造方法, a:" + a);
                a = 2;
            }

            protected void step() {
                System.out.println("base s: " + s + " , a : " + a);
            }

            public void action() {
                System.out.println("start");
                step();
                System.out.println("end");
            }
        }
        public class Child extends Base {
            public static int s;
            private int a;

            static {
                System.out.println("子类静态代码块, s:" + s);
                s = 10;
            }

            {
                System.out.println("子类实例代码块, a:" + a);
                a = 10;
            }

            public Child() {
                System.out.println("子类构造方法,a:" + a);
                a = 20;
            }

            protected void step() {
                System.out.println("child s: " + s + " , a: " + a);
            }
        }
        public static void main (String[]args ){
            System.out.println("------ new Child()");
            Child cc = new Child();
            System.out.println("\n------ cc.action()");
            cc.action();
            Base bb = c;
            System.out.println("\n-------bb.action()");
            bb.action();
            System.out.println("\n ------- bb.s: " + bb.s);
            System.out.println("\n ------- cc.s: " + cc.s);
        }

答:输出结果如下:

------ new Child()
基类静态代码块, s:0
子类静态代码块, s:0 //子类静态代码块比父类构造方法先执行
基类实例代码块, a:0 //实例代码块比构造方法先执行
基类构造方法, a:1
子类实例代码块, a:0
子类构造方法,a:10

//对于变量无论是类变量还是实例变量都是静态绑定访问的。
------ cc.action() 
start
child s: 10 , a: 20
end

//对于变量无论是类变量还是实例变量都是静态绑定访问的。
-------bb.action()
start
child s: 10 , a: 20
end

 ------- bb.s: 1

 ------- cb.s: 10

其实考察的是 Java 类加载与初始化,加载就是在第一次使用类时动态把类加载到内存,加载一个类会看其父类是否已经加载,如果没有则会先加载父类。类加载过程如下:分配内存保存类信息->给类变量赋默认值->加载父类->设置父子关系->执行类初始化代码;而类初始化过程(先执行父类再执行子类,父类执行时子类静态变量是有默认值 0 的)如下:定义静态变量时的赋值语句->静态初始化代码块;这些 OK 以后就进入实例初始化过程:定义实例变量时的赋值语句->实例初始化代码块->构造方法。 所以上面的结果基本就是这个流程,只是寻找要执行的实例方法时是从对象的实际类型信息开始查找的,找不到才会查父类;对于变量无论是类变量还是实例变量都是静态绑定访问的。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,742评论 18 399
  • 父类 static 块 1 执行 父类 静态成员staticSam1初始化 父类 静态成员staticSam2初始...
    YCix阅读 1,336评论 0 0
  • 一:java概述:1,JDK:Java Development Kit,java的开发和运行环境,java的开发工...
    ZaneInTheSun阅读 2,686评论 0 11
  • 记得看过一篇文章,人的一生至少要经历三种爱情。 part 1 你爱的人,但最终不能在一起。 一段刻骨铭心的初恋,...
    Lucia洁阅读 449评论 0 1
  • 穿梭在街头上看人来人往 行人匆匆走过, 就像这朦胧细雨从天空流逝一般, 落在脸上是泪, ...
    一凉微阅读 272评论 0 0