java 静态块和构造块等执行顺序分析学习

构造块:在类成员变量区域用大括号括起来的代码,和方法相比没有修饰,没有返回,没有参数;
静态块:在构造块前加 static修饰
静态代码块:静态块+静态变量
非静态代码块:普通类成员变量+构造块

程序执行顺序:静态代码块->非静态代码块->类构造方法

 1 public class Test {
 2
 3     static {
 4         System.out.println("静态块");
 5     }
 6
 7     {
 8         System.out.println("构造块");
 9     }
10
11     public Test(String str) {
12         System.out.println("构造函数"+str);
13     }
14
15     public static void main(String[] strings) {
16         Test t1 = new Test("t1");
17         Test t2 = new Test("t2");
18     }
19 }

执行结果为:

静态块
构造块
构造函数t1
构造块
构造函数t2

也就是说静态块会先于main函数执行;(没有main函数,程序还能执行吗?)
然后是main里面实例化对象,这时程序会跳到构造函数那一行,但不会直接执行构造函数中的内容,而是开始执行非静态代码块,等执行完这一部分之后再执行构造函数;
还有一点,从结果可以看出静态代码块只执行了一次。

有一种特殊情况,静态对象
在静态变量中new一个自身的对象

 1 public class Test {
 2
 3     public static int k = 0;
 4
 5     public static Test t1 = new Test("t1");
 6
 7     public static int i = print("i");
 8     public static int n = 99;
 9
10     public int y=0;
11     static {
12         System.out.println("静态块");
13         }
14
15     public int y1=0;
16     public int y2=0;
17     public int y3=0;
18     public int y4=0;
19     public int j1 = print("j1");
20     {
21         System.out.println("构造块");
22     }
23
24
25     public Test(String str) {
26         System.out.println((++k) + ":" + str + " i=" + i + " n=" + n);
27         ++i;
28         ++n;
29     }
30
31     public static int print(String str) {
32         System.out.println((++k) + ":" + str + " i=" + i +" n=" + n);
33         ++n;
34         return ++i;
35     }
36
37     public static void main(String[] strings) {
38         Test t = new Test("init");
39     }
40
41 }

执行结果:

1:j1 i=0 n=0
构造块
2:t1 i=1 n=1
3:i i=2 n=2
静态块
4:j1 i=3 n=99
构造块
5:init i=4 n=100

从结果中我们发现,”静态块“居然不是第一个输出,debug调试后发现执行顺序是
1.public static int k = 0;
2.public static Test t1 = new Test("t1");
3.public Test(String str) //构造函数,但不执行里面的内容
4.public int y=0;
5.public int y1=0;
...
6.public int j1 = print("j1");
7.System.out.println("构造块");
8.public Test(String str) { ...}//构造函数里面的内容

确实是先执行了静态块,不过遇到静态变量时
程序会先跳到构造函数,但不执行里面的内容,然后开始执行非静态代码块(注意 public int y=0; 也是非静态代码块中的一份子)
然后执行构造函数
所以才会出现了这样的结果

以下是执行顺序,抽之间重新画一下



以下是阿里的一到面试题
比上面的多一个地方
静态块和构造块中内容都是输出,在构造块之后又new了一个t2对象
不过没有关系,用上面的分析依然可以得到结果

 1 public class Test {
 2
 3   public static int k = 0;
 4
 5   public static Test t1 = new Test("t1");
 6   
 7   public static int i = print("i");
 8   public static int n = 99;
 9
10   static {
11     print("静态块");
12   }
13
14   public int j1 = print("j1");
15   {
16     print("构造块");
17   }
18
19   public int j = print("j");
20
21   public static Test t2 = new Test("t2");
22
23   public Test(String str) {
24     System.out.println((++k) + ":" + str + " i=" + i + " n=" + n);
25     ++i;
26     ++n;
27   }
28
29   public static int print(String str) {
30     System.out.println((++k) + ":" + str + " i=" + i +" n=" + n);
31     ++n;
32     return ++i;
33   }
34
35   public static void main(String[] strings) {
36   Test t = new Test("init");
37   }
38 }

结果为:

1:j1 i=0 n=0
2:构造块 i=1 n=1
3:j i=2 n=2
4:t1 i=3 n=3
5:i i=4 n=4
6:静态块 i=5 n=99
7:j1 i=6 n=100
8:构造块 i=7 n=101
9:j i=8 n=102
10:t2 i=9 n=103
11:j1 i=10 n=104
12:构造块 i=11 n=105
13:j i=12 n=106
14:init i=13 n=107

  



第一行输入代码为
public int j = print("j");
-->System.out.println((++k) + ":" + str + " i=" + i +" n=" + n);

这里输出了i的值为0,根据上面的分析,变量i的初始化即
public static int i = print("i");
这一行还没有执行到,那为什么不报错呢?

时间: 2024-10-29 00:14:16

java 静态块和构造块等执行顺序分析学习的相关文章

java类的初始化块/执行顺序,实例化对象数据赋值

java里初始化一个类的对象,通过初始化快或者构造方法进行数据赋值.与其相关的执行代码有这么几种: 静态初始化块 初始化块 构造方法 静态初始化块 静态初始化块只在类加载时执行一次,同时静态初始化块只能给静态变量赋值,不能初始化普通的成员变量. 非静态初始化块 非静态初始化块在每次初始化实例对象的时候都执行一次,可以给任意变量赋值. 构造方法 在每次初始化实例对象时调用. 重点:执行顺序-> 在加载类时执行一次静态初始化块(之后不再调用). 在每次初始化实例对象时:先执行非静态初始化块,再执行构

夯实Java基础系列7:一文读懂Java 代码块和执行顺序

目录 Java中的构造方法 构造方法简介 构造方法实例 例 1 例 2 Java中的几种构造方法详解 普通构造方法 默认构造方法 重载构造方法 java子类构造方法调用父类构造方法 Java中的代码块简介 Java代码块使用 局部代码块 构造代码块 静态代码块 Java代码块.构造方法(包含继承关系)的执行顺序 参考文章 微信公众号 Java技术江湖 个人公众号:黄小斜 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github

java中的构造块、静态块等说明

一:这篇博客写的时候我在学校已经一个星期了,为什么又会想到写这le,因为这几天又在重新学下有关spring.myBatis的知识,其中在实例化sessionFactory的时候用到了静态块,虽然在学习Hibernate时也用到过,那时候没现在想的深入.所以就回过头来记载下吧. 最近自己突然觉得做网页好没意思啊,强烈的感觉啊,现在觉得去学习android和ios很好,因为觉得做网页都是那几个框架,一成不变啊,写来写去都是这么做.看来自己在程序这方面做不久啊. 二:先说说静态块: static{ S

JAVA笔记5__构造块、静态块/单例设计模式/继承/final关键字/super关键字

public class Main { { //构造块(在构造对象时调用,先于构造方法执行) System.out.println("我是构造块!"); } static{ //静态块(在类加载时执行,且只执行一次[在构造块前执行]eg:数据库连接) System.out.println("我是静态块!"); } public Main(){ System.out.println("我是构造方法!"); } public static void

Java和Android中,代码块、static静态代码块的执行顺序

Java和Android中,代码块.static静态代码块的执行顺序有没有什么区别呢. Java 先来个简单的例子 Main.java: public class Main { static int a = 1; static { System.out.println(a); } static { a = 2; } public static void main(String[] args) { System.out.println("Hello World!"); System.ou

Java(静态)变量和(静态)代码块的执行顺序

本文讨论Java中(静态)变量.(静态)代码块的执行顺序 首先创建3个类: 1.Foo类,用于打印变量 public class Foo { public Foo(String word) { System.out.println(word); } } 2.Parent类 public class Parent { static Foo FOO = new Foo("Parent's static parameter"); Foo foo = new Foo("Parent'

面试趣闻之java 代码块 静态代码块 构造方法 执行顺序

初级程序员总会遇到这样的问题,代码块 静态代码块 构造方法 执行顺序 父类 public class ClassSup { public ClassSup(){ System.out.println("父类构造器"); } static { System.out.println("父类静态代码块"); } { System.out.println("父类代码块"); } public void mathod01(){ System.out.pri

一道面试题:静态代码块的执行顺序

先来看一道最常见的面试题:静态代码块的执行顺序? 看一下实际运行: class A{ static { System.out.println("A的静态代码块"); } { System.out.println("A的构造代码块/非静态代码块"); } public A() { System.out.println("A的构造函数"); } } class B extends A{ static { System.out.println(&quo

java中finally和return的执行顺序

注意:return的位置... 从这几个例子中可以看到,如果try之前没有有条件的return,则try..catch..finally语句块中的语句都是顺序执行(如果try中或者catch中 有return语句,那么先执行该return,然后执行finally, 如果finally中也有return, 该出的返回值会覆盖掉try 和 catch中的return值: 如果try..catch..finally语句块之后有return语句, try中.catch中.finally中都没有 (有条件