`
FlyingFairy
  • 浏览: 12691 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

Java静态代码块的问题

阅读更多

在查看别人代码的时候 看到了 static静态代码块  之后经过搜索和自己的亲试,下面贴出测试代码和解释。

package Test;
public class TestA {
	static {
		System.out.println("父类--静态代码块");
	}

	public TestA() {
		System.out.println("父类--构造方法");
	}

	{
		System.out.println("父类--非静态代码块");
	}

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

class TestB extends TestA {
	static {
		System.out.println("子类--静态代码块");
	}
	{
		System.out.println("子类--非静态代码块");
	}

	public Test() {
		System.out.println("子类--构造方法");
	}
}

 跑起来的结果是:

父类--静态代码块

子类--静态代码块

父类--非静态代码块

父类--构造方法

子类--非静态代码块

子类--构造方法

 

在这个代码中,代码的执行顺序,就是 在主类中首先执行static静态代码块中的代码,同理,之后在主函数中 建立了TestB对象,在执行构造函数之前,首先查看TestB中是否有static静态块,之后首先执行了静态代码块中的代码。当TestB的静态代码块执行完毕之后,它接着又去看A有没有非静态代码块,如果有就执行A类的非静态代码块,A的非静态代码块执行完毕,接着执行A的构造方法;A的构造方法执行完毕之后,它接着去看B有没有非静态代码块,如果有就执行B的非静态代码块。B类的非静态代码块执行完毕再去执行B类的构造方法,这个就是一个对象的初始化顺序。
噫,,写出来了好像挺麻烦的。。大致就是 1静态代码块  -->2非静态代码块  -->3构造方法

 

然后进行了有一个测试:

这个测试是测试是否一定是静态块先执行。

package Test;

public class TestA2 {
	private static TestA2 a = new TestA2();
	static {
		System.out.println("父类--静态代码块");
	}

	public TestA2() {
		System.out.println("父类--构造方法");
	}

	{
		System.out.println("父类--非静态代码块");
	}

	public static void main(String[] args) {
		new TestB2();
	}
}
class TestB2 extends TestA2 {
	private static TestB2 b = new TestB2();
	static {
		System.out.println("子类--静态代码块");
	}
	{
		System.out.println("子类--非静态代码块");
	}

	public TestB2() {
		System.out.println("子类--构造方法");
	}
}

 

结果如下:

父类--非静态代码块

父类--构造方法

父类--静态代码块

父类--非静态代码块

父类--构造方法

子类--非静态代码块

子类--构造方法

子类--静态代码块

父类--非静态代码块

父类--构造方法

子类--非静态代码块

子类--构造方法

这里先new了一个 静态的对象

	private static TestA2 a = new TestA2();

而 在静态代码块和创建静态对象时,是按照 代码的顺序执行的,就是说 需要执行完 这个创建对象的语句才能执行下面的 静态代码块中的语句。所以给人的感觉像是“跳过了”静态代码块,所以一开始是:1非静态代码块2构造方法。之后执行完了 创建对象的语句,继续执行,即静态代码块。之后就是在主类中创建一个TestB2对象,像上面的测试一样,不同的也只是在执行创建对象语句静态代码块和顺序的问题。而执行了两次非静态代码和构造方法的原因就是,一次是创建静态对象时,一次是执行完静态方法后的执行。

 

总结:
对象的初始化顺序:首先执行父类静态的内容,父类静态的内容执行完毕后,接着去执行子类的静态的内容,当子类的静态内容执行完毕之后,再去看父类有没有非静态代码块,如果有就执行父类的非静态代码块,父类的非静态代码块执行完毕,接着执行父类的构造方法;父类的构造方法执行完毕之后,它接着去看子类有没有非静态代码块,如果有就执行子类的非静态代码块。子类的非静态代码块执行完毕再去执行子类的构造方法。总之一句话,静态代码块内容先执行,接着执行父类非静态代码块和构造方法,然后执行子类非静态代码块和构造方法。

 

0
2
分享到:
评论
4 楼 孤烟客 2015-08-11  
QuarterLifeForJava 写道
2点不明,望楼主能详细讲解下:
1、为什么加上private static TestA2 a = new TestA2();
就变成了“父类--非静态代码块”-》“父类--静态代码块”
2、为什么将private static TestA2 a = new TestA2();中的static去掉
就报stack over flow了?

这段代码有一定的误导性。实际上前三个打印是加载主函数时候打印的,跟子类没什么关系,可以把main中的代码注释掉,更好理解。对于第一个问题,JVM在首次用到该类的时候会执行加载,连接,初始化的过程,这里所说的初始化就包括了静态变量的初始化和静态块的执行。当初始化变量a 时候,被要求构造TestA2 对象,这样不得不调用构造方法,但是jvm规范规定,调用构造方法前要先执行非静态块,所以就成了打印锁看到的样子:非静态块->构造方法->静态块,这样的过程。对于第二个问题,造成递归是必然的,调用构造函数前要初始化实例变量,这个过程包括了实例变量的初始化和非晶态块的执行,如果你改成了非静态变量,那么意味着在初始化实例变量的时候又要调用构造函数。程序会一直这样反复到崩溃。至此,两个问题解释完了,不知道可不可以帮到你
3 楼 QuarterLifeForJava 2015-08-10  
2点不明,望楼主能详细讲解下:
1、为什么加上private static TestA2 a = new TestA2();
就变成了“父类--非静态代码块”-》“父类--静态代码块”
2、为什么将private static TestA2 a = new TestA2();中的static去掉
就报stack over flow了?
2 楼 wensiqun 2015-08-10  
非静态程序块的内容编译器会写入到所有构造方法的最前面。所以把非静态程序块当作构造方法一部分可以了。
1 楼 jetable 2015-08-08  
Java的静态代码块功能很像.net的静态构造函数,是在加载该类的时候执行。

相关推荐

    java 静态代码块通过类加载器获取资源文件例子

    在Java编程中,静态代码块(Static Block)和类加载器(Class Loader)是两个重要的概念,它们在软件开发中有着广泛的应用。本案例聚焦于如何利用静态代码块结合类加载器来高效地获取资源文件,尤其是属性配置文件。...

    java静态代码块与非静态代码块参照.pdf

    Java 静态代码块与非静态代码块详解 Java 中的代码块可以分为静态代码块和非静态代码块两种,两者的执行时机和作用域不同。本文将通过实例代码和详细解释,阐述 Java 静态代码块与非静态代码块的区别和应用场景。 ...

    java静态代码块与非静态代码块.doc

    Java 静态代码块与非静态代码块 Java 中的静态代码块和非静态代码块是两个重要的概念,它们在 Java 中的应用非常广泛。下面我们来详细介绍这两个概念。 静态代码块 静态代码块是 Java 中的一种特殊的代码块,它是...

    Java静态代码块作用及执行顺序解析

    Java静态代码块作用及执行顺序解析 Java静态代码块是Java语言中的一种特殊代码块,它们在类加载的时候执行,且只执行一次。它们通常用来初始化静态变量、设置静态变量的初始值等。静态代码块的作用域是整个类,而...

    java 代码块与静态代码块加载顺序

    Java 代码块与静态代码块加载顺序详解 Java 代码块与静态代码块加载顺序是 Java 语言中一个重要的概念,理解这两个概念对于编写高效、可靠的 Java 代码至关重要。本文将详细介绍 Java 代码块与静态代码块加载顺序的...

    Java的静态代码块、非静态代码块、构造函数

    Java编程语言中,静态代码块、非静态代码块和构造函数是面向对象设计的重要组成部分,它们在类的初始化和对象创建过程中起到关键作用。本文将深入探讨这些概念,以及它们在实际开发中的应用。 首先,我们来理解静态...

    静态代码块

    静态代码块是Java语言中的一个重要概念,主要用于初始化类级别的数据成员或执行一些仅需执行一次的操作。静态代码块通过`static`关键字来定义,在类加载时执行,且只执行一次。这与实例构造器或普通代码块不同,后者...

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

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

    Java静态代码块加载驱动代码实例

    Java静态代码块加载驱动代码实例 Java静态代码块是一种特殊的代码块,它可以在类加载时被执行,该代码块只能被加载一次,无论new多少个对象。静态代码块通常用来加载配置文件、初始化操作等。 在Java中,静态代码...

    Java常见笔试、面试题目深度剖析,方法重写详解、静态代码块与构造方法执行顺序问题

    本文将深度剖析几个常见的Java面试题目,包括方法重写、静态代码块和构造方法的执行顺序。 首先,我们来讨论**方法重写(Override)**。在面向对象编程中,子类可以继承父类的属性和方法,有时需要根据自己的需求对...

    Java基础之代码块.docx

    静态块是指写在类中方法外的静态代码块,这种代码块的执行时机是类加载时。例如: ```java public class Demo01 { static { System.out.println("这是静态代码块"); } } ``` 在上面的代码中,静态块是写在 `Demo...

    关于Java中静态代码块的执行浅析

    Java中静态代码块的执行浅析 Java中的静态代码块是一种特殊的代码块,它们是在类加载过程中执行的,而不是在对象创建时执行的。静态代码块的执行是自动的,且只执行一次。在Java中,静态代码块的执行是static关键字...

    Java构造代码块,静态代码块原理与用法实例分析

    Java构造代码块、静态代码块原理与用法实例分析 Java构造代码块和静态代码块是Java中两种特殊的代码块,它们的运行机制和应用场景不同,下面将详细介绍Java构造代码块和静态代码块的原理、用法和注意事项。 一、...

    Java中的静态变量、静态方法与静态代码块

     其中静态代码在类的初始化阶段被初始化。而非静态代码则在类的使用阶段(也是实例化一个类的时候)才会被初始化。  静态变量  可以将静态变量理解为类变量(与对象无关),而实例变量则属于一个特定的对象...

    Java 中普通代码块,构造代码块,静态代码块区别及代码示例

    Java编程语言中有三种类型的代码块,它们分别是普通代码块、构造代码块和静态代码块,每种都有其特定的用途和执行顺序。 1. **普通代码块**: 普通代码块(也称为局部代码块)是在方法或者类的成员变量声明之间...

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

    静态块是Java类中用于初始化静态变量的代码块。它们在类加载时执行,且只执行一次。无论创建多少个类的实例,静态块只会被执行一次。这是因为在Java中,类的静态成员是与类相关的,而非类的实例。 ```java public ...

    Java:静态代码块和构造函数执行顺序

     1 静态变量,静态代码块(类加载时执行,类不加载不执行)  2 实例变量,实例代码块(创建对象时才执行,不创建对象不执行)  3 构造函数,(创建对象时执行完2后再执行构造函数,不管构造函数是public还是private...

    java中静态代码块与构造方法的执行顺序判断

    在Java编程语言中,了解静态代码块和构造方法的执行顺序是至关重要的,尤其是在处理类的初始化和对象的创建时。下面将详细解释这些概念及其执行逻辑。 首先,静态代码块(也称为静态初始化器)是由`static`关键字...

    Java中的static静态代码块的使用详解

    Java中的静态代码块是类级别的代码,它在类被加载到JVM(Java虚拟机)时执行,且只执行一次。这些代码块主要用于初始化类级别的变量,即静态变量。与静态方法不同,静态代码块是自动执行的,而静态方法需要通过类名...

Global site tag (gtag.js) - Google Analytics