几个问题(--------)父子类静态变量、静态代码块、非静态代码块、构造函数
来源:互联网 发布:淘宝店怎么做优惠卷 编辑:程序博客网 时间:2024/06/01 07:36
- class Parent{
- static String name = "hello";
- static {
- System.out.println("parent static block");
- }
- {
- System.out.println("parent block");
- }
- public Parent(){
- System.out.println("parent constructor");
- }
- }
- class Child extends Parent{
- static String childName = "hello";
- static {
- System.out.println("child static block");
- }
- {
- System.out.println("child block");
- }
- public Child(){
- System.out.println("child constructor");
- }
- }
- public class StaticIniBlockOrderTest {
- public static void main(String[] args) {
- new Child();//语句(*)
- }
- }
问题:当执行完语句(*)时,打印结果是什么顺序?为什么?
解答:当执行完语句(*)时,打印结果是这样一个顺序:parent static block,child static block,parent block,parent constructor,child block,child constructor。
分析:当执行new Child()时,它首先去看父类里面有没有静态代码块,如果有,它先去执行父类里面静态代码块里面的内容,当父类的静态代码块里面的内容执行完毕之后,接着去执行子类(自己这个类)里面的静态代码块,当子类的静态代码块执行完毕之后,它接着又去看父类有没有非静态代码块,如果有就执行父类的非静态代码块,父类的非静态代码块执行完毕,接着执行父类的构造方法;父类的构造方法执行完毕之后,它接着去看子类有没有非静态代码块,如果有就执行子类的非静态代码块。子类的非静态代码块执行完毕再去执行子类的构造方法,这个就是一个对象的初始化顺序。
总结:对象的初始化顺序:首先执行父类静态的内容,父类静态的内容执行完毕后,接着去执行子类的静态的内容,当子类的静态内容执行完毕之后,再去看父类有没有非静态代码块,如果有就执行父类的非静态代码块,父类的非静态代码块执行完毕,接着执行父类的构造方法;父类的构造方法执行完毕之后,它接着去看子类有没有非静态代码块,如果有就执行子类的非静态代码块。子类的非静态代码块执行完毕再去执行子类的构造方法。总之一句话,静态代码块内容先执行,接着执行父类非静态代码块和构造方法,然后执行子类非静态代码块和构造方法。
父类Static->子类static->父类缺省{}->父类构造函数->子类缺省{}->子类构造函数
解答:当执行完语句(*)时,打印结果是这样一个顺序:parent static block,child static block,parent block,parent constructor,child block,child constructor。
分析:当执行new Child()时,它首先去看父类里面有没有静态代码块,如果有,它先去执行父类里面静态代码块里面的内容,当父类的静态代码块里面的内容执行完毕之后,接着去执行子类(自己这个类)里面的静态代码块,当子类的静态代码块执行完毕之后,它接着又去看父类有没有非静态代码块,如果有就执行父类的非静态代码块,父类的非静态代码块执行完毕,接着执行父类的构造方法;父类的构造方法执行完毕之后,它接着去看子类有没有非静态代码块,如果有就执行子类的非静态代码块。子类的非静态代码块执行完毕再去执行子类的构造方法,这个就是一个对象的初始化顺序。
总结:对象的初始化顺序:首先执行父类静态的内容,父类静态的内容执行完毕后,接着去执行子类的静态的内容,当子类的静态内容执行完毕之后,再去看父类有没有非静态代码块,如果有就执行父类的非静态代码块,父类的非静态代码块执行完毕,接着执行父类的构造方法;父类的构造方法执行完毕之后,它接着去看子类有没有非静态代码块,如果有就执行子类的非静态代码块。子类的非静态代码块执行完毕再去执行子类的构造方法。总之一句话,静态代码块内容先执行,接着执行父类非静态代码块和构造方法,然后执行子类非静态代码块和构造方法。
父类Static->子类static->父类缺省{}->父类构造函数->子类缺省{}->子类构造函数
(静态变量、静态初始化块)>(变量、初始化块)>构造器
注意:子类的构造方法,不管这个构造方法带不带参数,默认的它都会先去寻找父类的不带参数的构造方法。如果父类没有不带参数的构造方法,那么子类必须用supper关键子来调用父类带参数的构造方法,否则编译不能通过。
注意:子类的构造方法,不管这个构造方法带不带参数,默认的它都会先去寻找父类的不带参数的构造方法。如果父类没有不带参数的构造方法,那么子类必须用supper关键子来调用父类带参数的构造方法,否则编译不能通过。
- class Parent {
- // 静态变量
- public static String p_StaticField = "父类--静态变量";
- // 变量
- public String p_Field = "父类--变量";
- // 静态初始化块
- static {
- System.out.println(p_StaticField);
- System.out.println("父类--静态初始化块");
- }
- // 初始化块
- {
- System.out.println(p_Field);
- System.out.println("父类--初始化块");
- }
- // 构造器
- public Parent() {
- System.out.println("父类--构造器");
- }
- }
- public class SubClass extends Parent {
- // 静态变量
- public static String s_StaticField = "子类--静态变量";
- // 变量
- public String s_Field = "子类--变量";
- // 静态初始化块
- static {
- System.out.println(s_StaticField);
- System.out.println("子类--静态初始化块");
- }
- // 初始化块
- {
- System.out.println(s_Field);
- System.out.println("子类--初始化块");
- }
- // 构造器
- public SubClass() {
- System.out.println("子类--构造器");
- }
- // 程序入口
- public static void main(String[] args) {
- new SubClass();
- }
- }
class Parent {// 静态变量public static String p_StaticField = "父类--静态变量";// 变量public String p_Field = "父类--变量";// 静态初始化块static {System.out.println(p_StaticField);System.out.println("父类--静态初始化块");}// 初始化块{System.out.println(p_Field);System.out.println("父类--初始化块");}// 构造器public Parent() {System.out.println("父类--构造器");}}public class SubClass extends Parent {// 静态变量public static String s_StaticField = "子类--静态变量";// 变量public String s_Field = "子类--变量";// 静态初始化块static {System.out.println(s_StaticField);System.out.println("子类--静态初始化块");}// 初始化块{System.out.println(s_Field);System.out.println("子类--初始化块");}// 构造器public SubClass() {System.out.println("子类--构造器");}// 程序入口public static void main(String[] args) {new SubClass();}}
运行一下上面的代码,结果马上呈现在我们的眼前:
- 父类--静态变量
- 父类--静态初始化块
- 子类--静态变量
- 子类--静态初始化块
- 父类--变量
- 父类--初始化块
- 父类--构造器
- 子类--变量
- 子类--初始化块
- 子类--构造器
可是静态代码块真的会一定在非静态代码块之前执行吗?
- public class ExA {
- private static ExA a = new ExA();
- static {
- System.out.println("父类--静态代码块");
- }
- public ExA() {
- System.out.println("父类--构造函数");
- }
- {
- System.out.println("父类--非静态代码块");
- }
- public static void main(String[] args) {
- new ExB();
- }
- }
- class ExB extends ExA {
- private static ExB b = new ExB();
- static {
- System.out.println("子类--静态代码块");
- }
- {
- System.out.println("子类--非静态代码块");
- }
- public ExB() {
- System.out.println("子类--构造函数");
- }
- }
public class ExA {private static ExA a = new ExA();static {System.out.println("父类--静态代码块");}public ExA() {System.out.println("父类--构造函数");}{System.out.println("父类--非静态代码块");}public static void main(String[] args) {new ExB();}}class ExB extends ExA {private static ExB b = new ExB();static {System.out.println("子类--静态代码块");}{System.out.println("子类--非静态代码块");}public ExB() {System.out.println("子类--构造函数");}}
执行结果
=====
父类--非静态代码块
父类--构造函数
父类--静态代码块
父类--非静态代码块
父类--构造函数
子类--非静态代码块
子类--构造函数
子类--静态代码块
父类--非静态代码块
父类--构造函数
子类--非静态代码块
子类--构造函数
=====
可以发现非静态代码块并不是一定在静态代码块之后执行的。
我认为此时private static ExA a = new ExA()是静态变量。而java里面静态变量与静态代码块是按代码先后顺序执行。所以就导致非静态代码块在静态代码块之前执行。
- 几个问题(--------)父子类静态变量、静态代码块、非静态代码块、构造函数
- 静态代码块,非静态代码块,构造函数
- JAVA代码块非静态代码块与静态代码块构造函数比较
- (static)静态代码块,非静态代码块和构造函数
- 父子类静态代码块,非静态代码块,有参,无参构造方法等的执行顺序问题
- java类加载及初始化过程(静态变量、静态代码块、代码块、构造函数)
- 静态代码块-非静态代码块-默认构造方法
- 构造函数、构造代码块、静态成员、静态代码块
- Java 静态变量,静态函数,静态代码块,构造代码块
- 父类和子类静态代码块、非静态代码块、构造函数(方法)执行的先后顺序问题
- 静态代码块、非静态代码块
- Java 静态变量、非静态代码块、构造函数的执行顺序
- 构造块/静态代码块
- 关于静态变量,静态代码块,实例变量,实例代码块,构造函数的执行顺序
- 静态变量、静态代码块、变量、代码块、构造函数执行顺序
- 类的加载、创建对象、静态变量static、构造函数、静态代码块、构造代码块、构造方法以及总结
- (非)静态代码块,构造函数,变量相关初始化顺序
- 静态方法(类方法),静态变量,静态代码块
- Co_Friends003
- 木马
- 从0开始
- 整理的一些protel封装名称
- 这题怎么处理?你会吗?
- 几个问题(--------)父子类静态变量、静态代码块、非静态代码块、构造函数
- PHP学习系列$第六章:FORACH循环
- 求助
- 学习、成长的一些感悟
- 一些bug1
- [转]《设计模式之禅》样章连载1:原型模式之“个性化电子账单”
- [转]《设计模式之禅》样章连载2:原型模式的定义及应用
- bug2
- 我心中的nba90年代四大中锋实力排名