`
cakin24
  • 浏览: 1367902 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

初始化块和构造器的执行顺序问题

    博客分类:
  • java
阅读更多

一 初始化块和构造器的执行顺序问题一般性规定

1 初始化块总在构造器之前执行,初始化块不能接受形参。

2 用static修饰的初始化块为静态初始化块,由于是静态的,所以是属于类,当类加载时,就执行静态初始化块,但执行一个子类时,最先执行其顶层父类的静态初始化。

3 如果初始化块是属于实例的,只要创建一次对象,初始化块就执行一次。

 

二 初始化块和构造器综合应用

1 代码示例

class Root
{
	static{
		System.out.println("Root的静态初始化块");
	}
	{
		System.out.println("Root的普通初始化块");
	}
	public Root()
	{
		System.out.println("Root的无参数的构造器");
	}
}
class Mid extends Root
{
	static{
		System.out.println("Mid的静态初始化块");
	}
	{
		System.out.println("Mid的普通初始化块");
	}
	public Mid()
	{
		System.out.println("Mid的无参数的构造器");
	}
	public Mid(String msg)
	{
		// 通过this调用同一类中重载的构造器
		this();
		System.out.println("Mid的带参数构造器,其参数值:"
			+ msg);
	}
}
class Leaf extends Mid
{
	static{
		System.out.println("Leaf的静态初始化块");
	}
	{
		System.out.println("Leaf的普通初始化块");
	}
	public Leaf()
	{
		// 通过super调用父类中有一个字符串参数的构造器
		super("软件秘笈");
		System.out.println("执行Leaf的构造器");
	}
}
public class Test
{
	public static void main(String[] args)
	{
		new Leaf();
		new Leaf();
	}
}

 2 运行结果

Root的静态初始化块

Mid的静态初始化块

Leaf的静态初始化块

Root的普通初始化块

Root的无参数的构造器

Mid的普通初始化块

Mid的无参数的构造器

Mid的带参数构造器,其参数值:软件秘笈

Leaf的普通初始化块

执行Leaf的构造器

Root的普通初始化块

Root的无参数的构造器

Mid的普通初始化块

Mid的无参数的构造器

Mid的带参数构造器,其参数值:软件秘笈

Leaf的普通初始化块

执行Leaf的构造器

3 结果分析

3.1 第一次创建第一个Leaf对象时,因为系统中还不存在Leaf类,因此需要先加载并初始化Leaf类,初始化Leaf类时会先执行其顶层父类静态初始化,再执行其直接父类的静态初始化块,最后才执行Leaf本身静态初始化块。

3.2 一旦Leaf类初始化成功后,Leaf类在该虛拟机中将一直存在,因此,当第二次创建Leaf实例时无须再对Leaf类进行初始化。

3.3普通初始化块和构造顺序与前面介绍的一致,每次创建一个Leaf对象时,都需先执行最顶层父类的初始化,构造器,然后执行其父类初始化,构造器…最后才执行Leaf类的初始化块和构造器。

 

三 静态初始化块与指定初始化值的静态成员执行顺序问题

1 代码示例

public class StaticInitTest
{
	// 先执行静态初始化块将a静态成员变量赋值为6
	static
	{
		a = 6;
	}
	// 再将a静态成员变量赋值为9
	static int a = 9;
	public static void main(String[] args)
	{
		// 下面代码将输出9
		System.out.println(StaticInitTest.a);
	}
}

2 运行结果

9

3 结果分析

当JVM第一次主动使用某个类时,系统会在类准备阶段为该类所有静态成员分配内存,在初始化阶段则负责初始化这些静态成员变量,初始化静态成员变量就是执行类初始化代码或声明类成员变量时的初始值,它们的执行顺序与源代码中的排列顺序相同。

0
0
分享到:
评论

相关推荐

    java程序初始化顺序

    - 构造器主体:最后,执行当前类的构造器主体,完成对象的具体初始化。 4. **多线程下的初始化**: - 当多个线程同时尝试初始化同一个类时,Java保证只会执行一次类的初始化过程。这是由JVM的同步机制保证的,...

    java面试题-类的初始化顺序.doc

    这个顺序表明,无论类之间的继承关系如何,初始化顺序始终是:静态变量和静态初始化块先于非静态成员。在创建对象时,父类的初始化先于子类。这是Java语言规范所规定的,确保在子类访问父类的静态或非静态成员时,...

    JAVA面试题解惑系列——类的初始化顺序

    在父类的构造器中使用某个还未初始化的子类静态成员变量(如果子类静态成员变量的初始化依赖于父类的某些数据或者执行顺序),就可能产生意料之外的行为,因为按照初始化顺序,子类静态成员变量会在父类构造器执行...

    Java初始化块Java初始化块.doc

    初始化块可以用于设置对象的初始状态,特别是当某些初始化逻辑需要在构造器之外的地方执行时。不过,需要注意的是,如果初始化块和属性声明中的初始值设定有冲突,属性声明的初始值设定会先执行,然后才是初始化块。...

    Java类继承初始化顺序

    3. **构造器**:父类的构造器执行完毕后,执行子类的构造器。如果子类构造器没有显式调用父类构造器(使用`super()`),Java会默认添加`super()`调用到构造器的最开始。 4. **子类成员变量初始化**:最后,执行子类...

    java代码的初始化顺序demo

    总之,Java代码的初始化顺序是类加载的必然过程,涉及到静态和实例初始化块、构造函数、成员变量初始化以及继承关系的影响。这个demo是学习和理解这些概念的重要工具,通过实际操作可以加深对Java内存管理和对象生命...

    对象初始化流程梳理对象初始化流程梳理

    - **子类构造器**:子类构造器负责设置子类的非静态属性初始值,如果在子类构造器执行前就已经返回了某个非静态属性,那么这个属性的值将是它的默认值(如基本类型为0或空引用,对象类型为null)。 这个例子中,...

    JAVA类的初始化顺序文.pdf

    1. **静态成员和静态初始化块**:首先,会按照父类到子类的顺序初始化静态变量和执行静态初始化块。在上面的例子中,"父类 --静态变量" 和 "子类 --静态变量" 先被初始化,然后分别执行对应的静态初始化块。 2. **...

    C++和Java初始化顺序的比较代码

    4. 实例初始化块:在构造器执行之前,按块的顺序执行。 例如: ```java public class MyClass { static int a = 1; // 静态字段初始化 static { a = 2; // 静态初始化块 } final int b = 3; // 常量字段 int ...

    Java初始化块及执行过程解析

    在 Java 中,对象的初始化方式主要有两种:构造器和初始化块。构造器是 Java 中常用的对象初始化方式,用于对对象进行初始化操作。初始化块也是对象初始化的一种方式,但它可以对 Java 对象进行更多的初始化操作。 ...

    java 静态块实例块构造器调用

    Java编程语言中,类的初始化过程涉及到静态块(static block)、实例块(instance block)以及构造器(constructor)。这些块的执行顺序对于理解和编写复杂的Java程序至关重要,特别是在涉及继承关系时。下面我们将...

    深入理解java构造器机理

    “深入理解Java构造器机理” 在 Java 编程语言中,构造器是一种特殊的方法,用于初始化对象的创建。它是 Java 类中最重要的...了解构造器的机理、执行顺序、作用及与其他概念的区别对于 Java 学习者和开发者非常重要。

    探究java的ClassLoader及类变量初始化顺序

    需要注意的是,静态初始化块只在类被加载时执行一次,而实例初始化块(构造函数)则会在每次创建类的实例时执行。静态变量的初始化是在类加载时完成的,而实例变量的初始化则在对象创建时进行。 在实际开发中,对...

    JAVA面试题解惑系列(一)——类的初始化顺序-JAVA程序员JAVA工程师面试必看.pdf

    1. **静态变量和静态初始化块**:首先,按照声明的顺序,执行父类的静态变量和静态初始化块,然后执行子类的静态变量和静态初始化块。这是因为静态成员属于类,不依赖于类的实例,所以在创建任何对象之前就已经完成...

    JAVA面试题解惑系列类的初始化顺序JAVA程序员JAVA工程师面试必看.pdf

    3. **父类的非静态部分**:在创建子类实例时,首先执行父类的非静态变量初始化和非静态初始化块,然后调用父类的构造器。 4. **子类的非静态部分**:最后执行子类的非静态变量初始化和非静态初始化块,以及子类的...

    再次详细说明在继承中的程序执行顺序,子类与父类到底哪个先执行

    综上所述,程序执行顺序的基本原则是:首先初始化并执行父类的构造器、静态和实例初始化块,然后执行子类的构造器、实例初始化块。最后,当通过子类对象调用方法时,优先执行子类覆盖的方法。理解这一顺序对于编写可...

    Java 普通代码块静态代码块执行顺序(实例讲解)

    这里我们将深入探讨Java中的普通代码块(实例初始化块)和静态代码块的执行顺序,并通过实例来阐述这一概念。 首先,我们需要明白两种类型的代码块: 1. 静态代码块(Static Block):这些代码块在类加载时执行,...

    SpringBoot项目启动时实现调用一次初始化方法.docx

    通过以上介绍,我们可以根据项目的需求选择合适的初始化方式,`@PostConstruct`适合简单的初始化,`CommandLineRunner`适合多个初始化步骤并控制执行顺序,而启动类中的初始化方法则更灵活,但应避免过度使用。...

    java学习之神奇初始化

    ### Java学习之神奇初始化 #### 知识点详解 在Java编程语言中,类的...综上所述,通过了解这些初始化顺序和规则,开发者可以更好地控制程序的行为,并确保类的正确初始化。这对于编写高效、可靠的Java程序至关重要。

Global site tag (gtag.js) - Google Analytics