综合网上的相关帖子和我自己的调试,研究了一下关于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
分享到:
相关推荐
在C#编程中,面向对象是核心特性之一,它提供了静态类、构造方法以及静态方法等概念,这些是创建高效、可维护代码的关键元素。让我们深入探讨这些知识点。 首先,静态类是C#中不能被实例化的类,它们只包含静态成员...
本文详细介绍了类继承中的初始化顺序问题,包括初始化的基本概念、初始化过程中的关键步骤以及如何正确处理基类和子类之间的构造函数调用。理解这些概念对于编写高效、可维护的面向对象程序至关重要。希望通过对这些...
总之,Java类继承初始化顺序涉及到静态和非静态初始化块、构造器的调用以及方法的覆盖。理解这些概念对于编写健壮的、易于维护的Java代码至关重要。在实际编程中,应合理利用继承特性,同时注意避免不必要的复杂性和...
4.知道了static的作用,那么X类被加载,那么就会先执行X类的静态属性和静态语句块(static),执行先后顺序看谁在前面就先执行谁。只在此时执行,以后都不会。 5.所以一个输出结果为tttt,没问题了吧。 6.X类的...
例如,如果一个类需要在程序运行前设置一个常量数组,静态初始化块就是合适的选择。 ```java public class InitFiledBlockStatic { static int[] staticArray; static { // 静态初始化块中的代码 staticArray ...
这是因为每个对象在创建时都需要先初始化其基类的部分,这通常意味着父类的构造函数会在子类构造函数之前调用。在Java中,如果子类没有显式地调用父类的构造函数,那么会默认调用父类的无参构造函数。 通过分析给定...
构造方法用于初始化类的新实例,普通方法执行特定任务,静态方法与类关联而非实例,抽象方法则在接口或抽象类中定义,需由子类实现。方法的参数传递、返回值和重载也是重要的知识点,理解这些能帮助我们编写更灵活...
### Java 类中静态域、块,非静态域、块,构造函数的初始化顺序 #### 一、概述 在 Java 编程语言中,类的初始化顺序对于理解程序的行为至关重要。特别是当涉及到静态域(静态变量)、非静态域(实例变量)、静态块...
3. **父类静态成员变量及初始化块**:如果当前类继承自另一个类,则父类的静态成员变量和静态初始化块会在子类之前被初始化。 4. **实例成员变量的默认初始化**:创建对象时,默认情况下,实例成员变量会被初始化为...
Java编程语言中,类的初始化过程涉及到静态块(static block)、实例块(instance block)以及构造器(constructor)。这些块的执行顺序对于理解和编写复杂的Java程序至关重要,特别是在涉及继承关系时。下面我们将...
在Java编程语言中,构造器(Constructor)是一个特殊的方法,主要负责对象的初始化工作。当创建一个新的类实例时,构造器会被自动调用。构造器的名称必须与类名完全相同,且没有返回类型,包括void。理解并熟练运用...
构造方法分为实例构造方法和类构造方法(即静态初始化块)。构造方法的执行顺序如下: 1. 首先,执行父类的静态代码块(如果有)。 2. 然后,执行当前类的静态代码块(如果有)。 3. 接着,调用父类的实例构造方法...
1. **静态成员变量优先于非静态成员变量**:无论是在父类还是子类中,静态成员变量都会在非静态成员变量之前初始化。 2. **继承关系中的初始化顺序**:在继承关系中,父类的成员变量与初始化块会在子类的对应部分...
在创建一个对象时,Java首先初始化类中的静态成员,然后是实例成员,最后才是构造方法。这意味着如果一个类中有多个成员变量,它们的初始化顺序将按照代码中声明的顺序进行。 #### 八、总结 构造方法是Java编程...
如果一个类是从另一个类继承的,子类的初始化会先调用父类的构造函数,确保父类的状态正确。然后,子类的实例初始化块和构造函数将依次执行。 7. **多线程环境下的初始化**: 如果多个线程同时尝试初始化同一个类...
动态初始化则涉及运行时的动作,比如需要函数调用或类构造函数的初始化。这些变量的初始化在main函数执行之前进行,但晚于静态初始化。这意味着如果一个全局变量依赖于其他全局变量的初始化结果,必须确保这些依赖的...
在修改后的 `Cow` 类中,当尝试给 `count` 或 `whatever` 赋值时,静态构造函数会先执行,确保这些静态变量的初始化。 总结一下,C# 中的静态类提供了无需实例化即可使用的功能,它们通常用于工具类或提供全局服务...
- **父类的静态初始化**:在类被加载到内存中时,会先执行父类的静态初始化块(如果有)。这里`Person`类的`static`块按照出现的顺序依次执行。 - **子类的静态初始化**:接着执行子类的静态初始化块,同样按照...
值得注意的是,如果在静态块中调用了`System.exit(0)`,程序会立即终止,不会继续执行后续的代码,包括其他静态块、初始化块和`main`方法。这是因为在调用`System.exit(0)`后,JVM会正常退出,不再执行任何Java代码...