`

关于继承类先初始化构造方法还是静态方法,静态方法在调用前会不会初始化?

阅读更多

综合网上的相关帖子和我自己的调试,研究了一下关于JAVA继承类的静态变量、成员变量、父子类构造方法调用顺序问题。首先看一段程序:

class X {
    Y b = new Y();//7、这里是父类成员变量初始化
    static Y sb= new Y();//1、父类静态变量,输出static Y(静态代码块先初始化),2、Y

    static{
        System.out.println("static X父类静态代码块");//3、执行静态代码块
        new Y();//4、这里只是输出Y,有static Y(静态代码块只执行一次)
    }
    X() {

        System.out.println("X");//8、父类成员变量初始化之后,执行父类构造器输出X
    }
}

class Y {
    static{
        System.out.println("static Y");       
    }
    Y() {//执行构造函数
        //这里有个super()==Object()
        System.out.println("Y");
    }
}

public class Z extends X {
    final static int mead=45;
    final byte b=16;
    static Y sb= new Y();//5、子类的静态变量,输出Y
    static{      
        System.out.println("static Z");//6、子类的静态代码块
    }
    Y y = new Y();//9、这里是子类成员变量初始化

    Z() {
        //这里有super()==new X()
        this.y = null;
        System.out.println("Z");//10、子类成员变量初始化之后,执行子类构造器输出Z
    }

    public static void main(String[] args) {
        new Z();

    }
}

 

执行结果:

static Y
Y
static X父类静态代码块
Y
Y
static Z
Y
X
Y
Z

解释:
static的东西在编译的时候就向内存要到了存取空间,他们的初始化要早于非static,顺序是先父类再子类。
初始化类,先执行super()父类的的构造函数(final和static之后),父类的构造函数先执行super()直到object super(),完了执行一般成员变量的初始化

一般成员变量初始化完毕,执行构造器里面的代码(super()之后的代码).
父类的初始化完成后(子类构造器里面super执行完毕),才轮到子类的成员变量初始化
子类成员变量初始化完毕,开始执行子类构造器里面的代码(super()之后的代码).

注意:

静态块和静态变量的调用顺序是按照书写顺序执行的,比如上边X类中静态块和静态变量的书写顺序颠倒如下:

class X {
  Y b = new Y();
       static{
        System.out.println("static X父类静态代码块");
        new Y();
    }
    static Y sb= new Y();
    X() {
        System.out.println("X");
    }
  
}

则执行结果为:

static X父类静态代码块
static Y
Y
Y
Y
static Z
Y
X
Y
Z

最后:

确定变量空间和初始化赋值是分开进行的,先一次性确定静态成员变量空间 并赋给二进制0 ,然后按照书写顺序逐一赋值

如下代码,输出结果是0.0

public class Test {
    static int i=f();
    static double d=0.1234;
    public static void main(String[] args) {
        new Test();
    }
    static int f(){
        System.out.println(d);
        return 3;
    }
}

 

    静态成员初始化在静态构造函数之前,静态构造函数调用在静态方法前,而静态成员初始化又是在什么时候调用的呢?
    类被首次提到(实例化或调用静态对象/方法)时开始执行类的静态成员初始化,初始化后如果存在静态构造函数则调用静态构造函数,之后进行相应操作。静态成员不会因为先调用而先初始化。

 

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/pisota/archive/2010/02/27/5332848.aspx

分享到:
评论

相关推荐

    java面试题静态加载顺序构造方法

    4.知道了static的作用,那么X类被加载,那么就会先执行X类的静态属性和静态语句块(static),执行先后顺序看谁在前面就先执行谁。只在此时执行,以后都不会。 5.所以一个输出结果为tttt,没问题了吧。 6.X类的...

    Java开发者文档,分享日常学习的一些小知识点 .rar

     ※在所有类成员初始化完成之后,才调用本类的构造方法创建对象。  构造方法的作用就是初始化。  (2) 静态对象的初始化  程序中主类的静态变量会在main方法执行前初始化。  不仅第一次创建对象时,类中的...

    JAVA基础知识精华总结 收藏

    (2) 常量在使用前必须赋值,但除了在声明的同时初始化外,就只能在构造方法中初始化 。 (3) final修饰的方法不能被重置(在子类中不能出现同名方法)。 (4) 如果声明一个类为final,则所有的方法均为final,无论...

    实验03 Java面向对象编程1.doc

    ○2在Student类建立构造方法初始化各域的值,并统计学生人数count; ○3创建分别获得各域(学号,姓名,性别和年龄)的public方法,以及分别设置各域(学号,姓名,性别和年龄)值的public方法(即get、set方法);...

    10个Java经典的Main方法面试题!

    在 Java 7 之前,你可以通过使用静态初始化运行 Java 类。但是,从 Java 7 开始就行不通了。 3.main 方法如何传递参数?传递参数的类型是什么?能不能改变该参数类型? String 数组,不能改变。 4.main 方法为什么是...

    《java面向对象程序设计-继承和多态》教案.doc

    圆点符号用于访问对象的成员,构造函数在创建对象时初始化对象 包可用package 来申明 ,可用import 来导入包 目标 理解继承及其特点 运用JAVA程序实现继承 理解多态及其特点设计 运用JAVA程序实现多态 掌握访问修饰...

    C# 静态构造函数使用

    这个静态构造函数属于类,而不属于实例,是说这个构造函数只会被执行一次,即:在创建第一个实例或引用任何静态成员之前,由.NET自动调用。  现在碰到这样一个场景:提供一个静态方法,这个静态方法在不同的地方...

    C#静态构造函数用法实例分析

    这个静态构造函数属于类,而不属于实例,就是说这个构造函数只会被执行一次,即:在创建第一个实例或引用任何静态成员之前,由.NET自动调用。 现在碰到这样一个场景:提供一个静态方法,这个静态方法在不同的地方...

    【04-面向对象(上)】

    •用static修饰的初始化块为静态初始化块,由于是静态的,所以是属于类,当类加载时,就执行静态初始化块 ,  但执行一个子类时,最先执行其最顶层父类的静态初始化, •初始化块是属于实例 的。只要创建一次...

    【Java语言基础】初始化块

    文章目录【Java语言基础】初始化块使用初始化块静态初始化块总结代码 【Java语言基础】初始化块 初始化块又称为代码块。属于类中的第四大成员。本质上是一个方法,它也有方法体,但没有方法名,没有参数,没有返回,...

    【05-面向对象(下)】

    •接口的继承和类继承不一样,接口完全支持多继承,子接口扩展某个父接口将会获得父接口的所有抽象方法,常 量属性,内部类和枚举类定义。 使用接口 •接口可以用于声明引用类型的变量,但接口不能用于...

    Java 基础核心总结 +经典算法大全.rar

    类的初始化 成员初始化 构造器初始化初始化顺序 数组初始化 对象的销毁 对象作用域 this 和 super 访问控制权限继承 多态组合代理 向上转型static final 接口和抽象类接口 抽象类异常 认 识 Exception 什么是 ...

    java面试宝典

    141、使用useBean标志初始化BEAN时如何接受初始化参数 36 142、使用JSP如何获得客户浏览器的信息? 36 143、能象调用子程序一样调用JSP吗? 36 144、当我重编译我的JSP使用的一个类后,为什么JVM继续使用我的老CLASS...

    千方百计笔试题大全

    141、使用useBean标志初始化BEAN时如何接受初始化参数 36 142、使用JSP如何获得客户浏览器的信息? 36 143、能象调用子程序一样调用JSP吗? 36 144、当我重编译我的JSP使用的一个类后,为什么JVM继续使用我的老CLASS...

    c# 9.0新特性——模块初始化器

    当前静态构造函数方法的一个最大的问题是运行时会对带有静态构造函数的类型做一些额外的检查。这是因为要决定静态构造函数是否需要被运行所必须的一步,但是这个又有着显著的开销影响。 使源代码生成器在不需要...

    java中千万别乱用!Lombok不是万能的

    在构建器中:对于目标类中的所有的属性和未初始化的 final 字段,都会在构建器中创建对应属性 在构建器中:创建一个无参的 default 构造函数 在构建器中:实体类中的每个参数,都会对应创建类似于 setter 的方法,...

    java 面试题 总结

    finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。 13、sleep() 和 wait() 有什么区别? sleep是线程类(Thread)的...

    学习C#静态函数及变量的一个精典例子与代码

     (3)类的静态构造函数在给定应用程序域中至多执行一次:只有创建类的实例或者引用类的任何静态成员才激发静态构造函数 (4)静态构造函数是不可继承的,而且不能被直接调用。 (5)如果类中包含用来开始执行的...

    java编程练习题

    4,写一个类Fish,继承自Animal类,并提供一个构造方法,该构造方法需要一个参数name,并给legs赋默认值0;该类还要求覆盖Animal类中的无参move()方法,要求输出:XXX Swimming!! 5,写一个类Bird,继承自Animal类,并...

    JAVA面试题最全集

    51.Object类(或者其子类)的finalize()方法在什么情况下被调用? 52.一个“.java”原文件中是否可以包括多个类(不是内部类)? 53.掌握内部类和接口的概念 54.StringTokenizer类的使用 55.数据结构,如何遍历...

Global site tag (gtag.js) - Google Analytics