变量、初始化块和构造方法的初始化顺序问题(笔试题)

简介: 在某公司面试时碰见的该题目, 给出如下程序,让写出程序打印的语句的顺序,也就是程序加载执行的过程。 当时确实有些懵了,只根据大体印象写了答案。回来后写程序跑了一遍,自己还真是没猜对。所以贴出来帮助记忆并与大家共赏!! package com.skd.timu;public class Demo4 { public static void main(String[] args

在某公司面试时碰见的该题目,

给出如下程序,让写出程序打印的语句的顺序,也就是程序加载执行的过程。

当时确实有些懵了,只根据大体印象写了答案。回来后写程序跑了一遍,自己还真是没猜对。所以贴出来帮助记忆并与大家共赏!!

package com.skd.timu;

public class Demo4 {
	public static void main(String[] args) {
		new childrenDemo();
		new childrenDemo();
	}
}

class ParentDemo{
	 static	String staParentString="父类-静态-变量";
	 String parentString="父类-非静态-变量";
	
	 static{
		 System.out.println(staParentString);
		 System.out.println("父类 -  静态 - 初始化块");
	 }
	 {
		 System.out.println(parentString);
		 System.out.println("父类 - 非静态 - 初始化块");
	 }
	 ParentDemo(){
		 System.out.println("父类-构造方法");
	 }
}

class  childrenDemo extends ParentDemo{
	static	String staChildrenString="子类-静态-变量";
	 String childrenString="子类-非静态-变量";
	
	 static{
		 System.out.println(staChildrenString);
		 System.out.println("子类 -  静态 - 初始化块");
	 }
	 {
		 System.out.println(childrenString);
		 System.out.println("子类- 非静态 - 初始化块");
	 }
	 childrenDemo(){
		 System.out.println("子类-构造方法");
	 }
}



看完该程序不妨自己先写个输出语句的顺序然后写程序执行看是否与自己的判断一致。

先把程序执行的结果贴上:

父类-静态-变量
父类 -  静态 - 初始化块
子类-静态-变量
子类 -  静态 - 初始化块
父类-非静态-变量
父类 - 非静态 - 初始化块
父类-构造方法
子类-非静态-变量
子类- 非静态 - 初始化块
子类-构造方法
父类-非静态-变量
父类 - 非静态 - 初始化块
父类-构造方法
子类-非静态-变量
子类- 非静态 - 初始化块
子类-构造方法


从输出结果可以看出,静态变量和静态初始化块只在程序加载的时候执行一次,执行次序在最前面,是全局的;

构造块的加载顺序在静态块之后但在构造方法之前,而且在构造块加载之前,变量已经加载;

构造方法是在静态变量,静态块,变量,构造块后才加载的,是在类实例化时,除了调用方法外的最后加载的位置;

因为静态变量和静态块都是全局的,因此在程序加载时就已经加载,不会因为是子类中的静态变量和静态块就比父类的构造块加载晚,但在都是静态变量或静态块的情况下,

总是先初始化父类的,然后初始化子类的。

同样的因为构造块和构造方法不是全局的,而且子类在实例化时总是先调用父类的构造块和构造方法,因此父类的构造块和构造方法在子类的之前调用。即在实例化子类时,程序会先调用父类的实例化构造块或者构造方法,然后才会调用子类的构造块和构造方法完成子类的实例化。

而且,构造块和构造方法会在每次实例化的时候都执行,静态变量和静态块只会执行一次(不管该类实例化多少对象)。






相关文章
|
6天前
|
存储
成员变量和类变量的区别:
成员变量和类变量的区别:
|
8月前
|
存储 编译器 C语言
【C++基础】类与对象(中):默认成员函数、构造函数、析构函数、拷贝构造、赋值重载函数……
【C++基础】类与对象(中):默认成员函数、构造函数、析构函数、拷贝构造、赋值重载函数……
66 0
|
5月前
|
编译器 C++
一文搞懂C++构造函数的初始化列表
我们在实例化对象后,对象自动调用构造函数来初始化自己的值,完成初始化工作,但是我们并不能称它为成员变量的初始化,因为初始化只能初始化一次,然而在函数体的“初始化”工作,准确的说可以赋值多次,所以把函数体赋值当作初始化,有失偏颇。 因此引入初始化列表
62 0
|
6月前
|
编译器 C++
【C++】类与对象 (四)初始化列表 static成员 友元 内部类 匿名对象 拷贝对象时的一些编译器优化(1)
【C++】类与对象 (四)初始化列表 static成员 友元 内部类 匿名对象 拷贝对象时的一些编译器优化
|
6月前
|
Java 编译器 C语言
【C++】类与对象 (四)初始化列表 static成员 友元 内部类 匿名对象 拷贝对象时的一些编译器优化(2)
【C++】类与对象 (四)初始化列表 static成员 友元 内部类 匿名对象 拷贝对象时的一些编译器优化(1)
|
10月前
|
存储 编译器 C语言
【C++学习】类和对象 | 再谈构造函数 | 构造函数中的隐式类型转换 | static静态成员
【C++学习】类和对象 | 再谈构造函数 | 构造函数中的隐式类型转换 | static静态成员
64 0
|
11月前
|
Java
Java中类的初始化过程:(静态成员变量,静态代码块,普通成员变量,代码块初始化顺序)
Java中类的初始化过程:(静态成员变量,静态代码块,普通成员变量,代码块初始化顺序)
104 0
|
12月前
|
存储
局部变量和成员变量的4个区别
定义位置不同、内存中的位置不同、周期不同、初始化不同。
99 0
|
Android开发
构造函数与初始化块
构造函数与初始化块
120 0
|
存储 Java
JavaSE面试题——成员变量(类变量 & 实例变量) & 局部变量
JavaSE面试题——成员变量(类变量 & 实例变量) & 局部变量
JavaSE面试题——成员变量(类变量 & 实例变量) & 局部变量