Java语法专题2: 类变量的初始化顺序
- 合集目录
- Java语法专题2: 类变量的初始化顺序
问题
这也是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();
}
}
分析
正确回答这些问题, 需要对以下的概念有了解:
static关键字, 静态变量和静态方法- 静态变量和普通成员变量初始化的区别
- 类初始化中父类和子类变量的初始化顺序
以下通过具体场景说明
场景一: 单个类的初始化顺序
先看单个类的初始化顺序, 静态和普通变量都根据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
可以得到以下信息
- 静态成员变量初始化最早
- 与实例初始化无关, 在载入类时完成初始化
- 初始化顺序与代码顺序一致, 与public还是private无关
- 静态成员变量初始化在执行main()函数之前完成, 因为在执行main()函数前, 静态成员初始化就伴随类的载入完成了
- 普通成员变量初始化在执行构造函数之前
场景二: 带继承关系的类初始化顺序
保持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
可以得到以下信息
- 在任何情况下, 静态成员变量都会最先初始化
- 在存在继承关系的类中, 父类的静态成员变量先初始化, 然后是子类的静态成员变量
- 所有静态成员变量初始化之后, 才开始main函数的执行
- 在类实例初始化过程中, 先初始化父类, 再初始化子类, 每一层都是先成员变量, 然后执行构造函数, 所以顺序就是: 父类成员变量, 父类构造函数, 子类成员变量, 最后是子类构造函数
总结
类的构造顺序为
- 父类静态成员变量, 其顺序与代码顺序一致, 与public还是private无关
- 子类静态成员变量, 其顺序与代码顺序一致, 与public还是private无关
- 如果执行类的静态函数(包括main函数), 这个时间点就会开始执行函数
- 如果创建了类的实例, 注意这个前提, 下面就会开始普通成员变量的初始化
- 父类的普通成员变量
- 父类的构造函数
- 子类的普通成员变量
- 子类的构造函数
Java语法专题2: 类变量的初始化顺序的更多相关文章
- Java语法专题1: 类的构造顺序
合集目录 Java语法专题1: 类的构造顺序 问题 下面的第二个问题来源于Oracle的笔试题, 非常经典的一个问题, 我从07年开始用了十几年. 看似简单, 做对的比例不到2/10. 描述一下多级继 ...
- Java类继承关系中的初始化顺序
Java类初始化的顺序经常让人犯迷糊,现在本文尝试着从JVM的角度,对Java非继承和继承关系中类的初始化顺序进行试验,尝试给出JVM角度的解释. 非继承关系中的初始化顺序 对于非继承关系,主类Ini ...
- Java杂谈3——类加载机制与初始化顺序
Java语言的哲学:一切都是对象.对于Java虚拟机而言,一个普通的Java类同样是一个对象,那如果是对象,必然有它的初始化过程.一个类在JVM中被实例化成一个对象,需要经历三个过程:加载.链接和初始 ...
- IT兄弟连 Java语法教程 数组 数组的初始化
Java语言中数组必须先初始化,然后才可以使用.所谓初始化,就是为数组的数组元素分配内存空间,并为每个数组元素赋初始值. 这时有人会问,能不能只分配内存空间,不赋初始值呢?答案是肯定不行的,一旦为数组 ...
- Java中类的数据成员的初始化顺序
对于单一类: 属性初始化 ---> 按顺序执行静态初始化块(只能操作静态属性) ---> 按顺序执行初始化块 ---> 构造方法 对于存在继承关系的类: 父类属性初始化 ---> ...
- java类的加载以及初始化顺序
类的加载和初始化的了解对于我们对编程的理解有很大帮助,最近在看类的记载方面的问题.从网上查阅了若干文章,现总结如下: 我们通过一段代码来了解类加载和初始化的顺序: package com.classl ...
- Java中含有静态成员的的初始化顺序
class Bowl{ Bowl(int marker){ System.out.println("Bowl(" + marker + ")" ); } voi ...
- java对象中继承和变量初始化顺序浅析
先上例子代码 public class F { int age = 5; public F() { print(); } public void print() { System.out.printl ...
- 【深入理解JVM】:Java类继承关系中的初始化顺序
尝试着仔细阅读thinking in java 看到一篇很好的文章http://blog.csdn.net/u011080472/article/details/51330114
随机推荐
- 1114 - Easily Readable
1114 - Easily Readable PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 32 MB ...
- centos 与虚拟机
一 创建虚拟机 1. 下载 centos7 和 vmware .centos的下载地址:见上一篇. 2.安装vmware ,具体安装过程,自行百度(一路点击确定) 3.打开vmware ,点击创建新的 ...
- Codeforces 567B:Berland National Library(模拟)
time limit per test : 1 second memory limit per test : 256 megabytes input : standard input output : ...
- [云原生]Kubernetes - 集群搭建(第2章)
目录 一.前置知识点 二.kubeadm部署方式介绍 三.安装要求 四.最终目标 五.准备环境 六.环境初始化 6.1 设置系统主机名以及Hosts文件的相互解析 6.2 安装依赖文件(所有节点) 6 ...
- Python_类型转换
列表与字符串互相转换 join方法将list转换为string _list = ["a", "b", "c"] # 以".&quo ...
- Linux shell 脚本中使用 alias 定义的别名
https://www.cnblogs.com/chenjo/p/11145021.html 核心知识点: 用 shopt 开启和关闭 alias 扩展 交互模式下alias 扩展默认是开启的,脚本模 ...
- spring cloud Zuul 多层拦截 --- 心得
1.前言 根据教材.博客文章的实例实操,基本都是单层拦截,没有找到多层拦截的具体写法 ,让我走了很多弯路,我将其写在这里,以待以后参考. 2.环境 spring boot : 2.1.6.RELEAS ...
- (随手记)Javascript 的parseInt函数,在IE和非IE内核浏览器运行的不同结果
一段JS小程序: var str = "09"; var itr = parseInt(str); alert(itr); IE下运行,alert(0); 火狐和chrome下运行 ...
- centos 操作系统优化
命令提示符优化 修改PS1环境变化 vim /etc/profile #在最后一行添加 export PS1='[\u@\H \w]$' \u ---显示当前登录用户名称 \h ---显示系统主机名称 ...
- vue 表格树 固定表头
参考网上黄龙的表格树进行完善,并添加固定表头等的功能,目前是在iview的项目中实现,如果想在element中实现的话修改对应的元素标签及相关写法即可. <!-- @events @on-row ...