问题

这也是Java面试中出镜率很高的基础概念问题

  • 描述一下多级继承中字段初始化顺序
  • 描述一下多级继承中类变量初始化顺序
  • 写出运行以下代码时的控制台输出
public class Base {
public static int v1 = method(1);
private static int v2 = method(2); private int v3;
private int v4 = method(3); public Base() {
v3 = method(4);
}
public static int method(int i) {
System.out.println(i);
return i;
}
public static void main(String args[]) {
method(5);
Base b2 = new Base();
}
}

分析

正确回答这些问题, 需要对以下的概念有了解:

  1. static关键字, 静态变量和静态方法
  2. 静态变量和普通成员变量初始化的区别
  3. 类初始化中父类和子类变量的初始化顺序

以下通过具体场景说明

场景一: 单个类的初始化顺序

先看单个类的初始化顺序, 静态和普通变量都根据public和private区分, 交替声明.

Base.java

public class Base {
public static int pub_s = method(1);
private static int pri_s = method(2);
public static int pub_s2 = method(3);
private static int pri_s2 = method(4); private int pri1;
private int pri2 = method(5);
private int pri3;
private int pri4 = method(6); public Base() {
pri1 = method(7);
pri3 = method(8);
}
public static int method(int i) {
System.out.println(i);
return i;
}
public static void main(String args[]) {
method(0);
Base b2 = new Base();
}
}

输出结果为

1
2
3
4
0
5
6
7
8

可以得到以下信息

  1. 静态成员变量初始化最早

    • 与实例初始化无关, 在载入类时完成初始化
    • 初始化顺序与代码顺序一致, 与public还是private无关
  2. 静态成员变量初始化在执行main()函数之前完成, 因为在执行main()函数前, 静态成员初始化就伴随类的载入完成了
  3. 普通成员变量初始化在执行构造函数之前

场景二: 带继承关系的类初始化顺序

保持Base.java不变, 增加Sub.java作为子类

Sub.java

public class Sub extends Base {
public static int sub_pub_s = method(11);
private static int sub_pri_s = method(12);
public static int sub_pub_s2 = method(13);
private static int sub_pri_s2 = method(14); private int sub_pri1;
private int sub_pri2 = method(15);
private int sub_pri3;
private int sub_pri4 = method(16); public Sub() {
sub_pri1 = method(17);
sub_pri3 = method(18);
}
public static void main(String args[]) {
method(10);
Sub b2 = new Sub();
}
}

运行Sub.java, 输出结果为

1
2
3
4
11
12
13
14
10
5
6
7
8
15
16
17
18

可以得到以下信息

  1. 在任何情况下, 静态成员变量都会最先初始化
  2. 在存在继承关系的类中, 父类的静态成员变量先初始化, 然后是子类的静态成员变量
  3. 所有静态成员变量初始化之后, 才开始main函数的执行
  4. 在类实例初始化过程中, 先初始化父类, 再初始化子类, 每一层都是先成员变量, 然后执行构造函数, 所以顺序就是: 父类成员变量, 父类构造函数, 子类成员变量, 最后是子类构造函数

总结

类的构造顺序为

  1. 父类静态成员变量, 其顺序与代码顺序一致, 与public还是private无关
  2. 子类静态成员变量, 其顺序与代码顺序一致, 与public还是private无关
  3. 如果执行类的静态函数(包括main函数), 这个时间点就会开始执行函数
  4. 如果创建了类的实例, 注意这个前提, 下面就会开始普通成员变量的初始化
  5. 父类的普通成员变量
  6. 父类的构造函数
  7. 子类的普通成员变量
  8. 子类的构造函数

Java语法专题2: 类变量的初始化顺序的更多相关文章

  1. Java语法专题1: 类的构造顺序

    合集目录 Java语法专题1: 类的构造顺序 问题 下面的第二个问题来源于Oracle的笔试题, 非常经典的一个问题, 我从07年开始用了十几年. 看似简单, 做对的比例不到2/10. 描述一下多级继 ...

  2. Java类继承关系中的初始化顺序

    Java类初始化的顺序经常让人犯迷糊,现在本文尝试着从JVM的角度,对Java非继承和继承关系中类的初始化顺序进行试验,尝试给出JVM角度的解释. 非继承关系中的初始化顺序 对于非继承关系,主类Ini ...

  3. Java杂谈3——类加载机制与初始化顺序

    Java语言的哲学:一切都是对象.对于Java虚拟机而言,一个普通的Java类同样是一个对象,那如果是对象,必然有它的初始化过程.一个类在JVM中被实例化成一个对象,需要经历三个过程:加载.链接和初始 ...

  4. IT兄弟连 Java语法教程 数组 数组的初始化

    Java语言中数组必须先初始化,然后才可以使用.所谓初始化,就是为数组的数组元素分配内存空间,并为每个数组元素赋初始值. 这时有人会问,能不能只分配内存空间,不赋初始值呢?答案是肯定不行的,一旦为数组 ...

  5. Java中类的数据成员的初始化顺序

    对于单一类: 属性初始化 ---> 按顺序执行静态初始化块(只能操作静态属性) ---> 按顺序执行初始化块 ---> 构造方法 对于存在继承关系的类: 父类属性初始化 ---> ...

  6. java类的加载以及初始化顺序

    类的加载和初始化的了解对于我们对编程的理解有很大帮助,最近在看类的记载方面的问题.从网上查阅了若干文章,现总结如下: 我们通过一段代码来了解类加载和初始化的顺序: package com.classl ...

  7. Java中含有静态成员的的初始化顺序

    class Bowl{ Bowl(int marker){ System.out.println("Bowl(" + marker + ")" ); } voi ...

  8. java对象中继承和变量初始化顺序浅析

    先上例子代码 public class F { int age = 5; public F() { print(); } public void print() { System.out.printl ...

  9. 【深入理解JVM】:Java类继承关系中的初始化顺序

    尝试着仔细阅读thinking in java 看到一篇很好的文章http://blog.csdn.net/u011080472/article/details/51330114

随机推荐

  1. 【九度OJ】题目1441:人见人爱 A ^ B 解题报告

    [九度OJ]题目1441:人见人爱 A ^ B 解题报告 标签(空格分隔): 九度OJ 原题地址:http://ac.jobdu.com/problem.php?pid=1441 题目描述: 求A^B ...

  2. 【LeetCode】859. Buddy Strings 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 字典 日期 题目地址:https://leetcod ...

  3. Beautiful Walls

    [1553] Beautiful Walls 时间限制: 1000 ms 内存限制: 65535 K 问题描述 To simplify the building process, XadillaX b ...

  4. Pytorch 图片载入

    目录 载入图片和坐标 Transforms Compose transforms 数据集的迭代 import os import torch import pandas as pd from skim ...

  5. <数据结构>XDOJ323.判断有向图中是否有环

    问题与解答 问题描述 判断有向图中是否有环. 输入格式 输入数据第一行是一个正整数,表示n个有向图,其余数据分成n组,每组第一个为一个整数,表示图中的顶点个数n,顶点数不超过100,之后为有向图的邻接 ...

  6. SpringCloud发现服务代码(EurekaClient,DiscoveryClient)

    1.说明 本文介绍SpringCloud发现服务代码的开发, 通过使用EurekaClient,DiscoveryClient来发现注册中心的服务等, 从而可以自定义客户端对注册中心的高级用法. 2. ...

  7. Location配置项及LNMP架构

    目录 Location配置项及LNMP架构 Location location匹配符号 LNMP架构 UWSGI uwsgi服务部署 部署BBS项目 步骤 Location配置项及LNMP架构 Loc ...

  8. CSS基础 transform属性的基本使用 移动 旋转 缩放

    1.实现元素位移效果 语法:transform:translate(x轴水平移动距离,Y轴垂直移动距离) 取值:正负都可以 取值方式:数字+px 百分比 :参照自己本的盒子的百分比 比如:本身自己的宽 ...

  9. Django_测试板块(六)

    本文初略的记录了Django测试板块相关信息,详情请阅官方文档:https://docs.djangoproject.com/zh-hans/3.1/topics/testing/ 开始写我们的第一个 ...

  10. xml文件 加载properties文件的两种方法与注意事项

    1.遇到的问题: 配置redisSpringContext.xml 时,遇到 properties加载失败,提示BeanDefinitionStoreException  和   java.lang. ...