之前一直只知道有静态代码块。后来才知道还有一个非静态代码块。
静态代码块是指由 static
修饰的大括号里的一段代码,那么非静态代码块就是没有修饰的大括号里的一段代码。就像下面:
# 静态代码块
static {
若干代码,随便写点啥吧。。。。
}
# 非静态代码块
{
若干代码,随便写点啥吧。。。。
}
他们的共同特点是:方法名、作用域、返回值、参数一概没有。
详情解析
我们先提出几个问题:
- 静态和非静态这两种代码块的区别是什么?
- 它们之间的执行顺序是怎么样?和构造函数间的执行顺序又是怎么样的?
- 当有继承情况存在的时候,它们的执行顺序又是怎么样?
带着问题,进行接下来的代码分析:
package com.sunyu.javaBase.aboutClass;
public class LoadOrder {
public static void main(String[] args) {
/**
一般情况下的代码测试
*/
parentTest();
/**
* 有继承情况存在下的代码测试
*/
childrenTest();
}
/**
* 父类测试
*/
public static void parentTest() {
Parent parent = new Parent();
System.out.println();
System.out.println("-------- 这是两次实例化的分割线 ---------");
System.out.println();
parent = new Parent("父类测试");
}
/**
* 子类测试
*/
public static void childrenTest() {
Children children = new Children();
System.out.println();
System.out.println("-------- 这是两次实例化的分割线 ---------");
System.out.println();
children = new Children("子类测试");
}
}
class Parent {
{
System.out.println("父类:执行非静态代码块");
}
static {
System.out.println("父类:执行静态代码块");
}
static String name;
Parent() {
System.out.println("父类:执行无参构造函数");
}
Parent(String name) {
System.out.println("父类:执行有参构造函数 --->" + name);
}
}
class Children extends Parent {
{
System.out.println("子类:执行非静态代码块");
}
static {
System.out.println("子类:执行静态代码块");
}
static String name;
Children() {
System.out.println("子类:执行无参构造函数");
}
Children(String name) {
System.out.println("子类:执行有参构造函数 --->" + name);
}
}
在上面的代码中定义了:主类 LoadOrder
,父类 Parent
,子类 Children
。
执行
image.pngparentTest()
,测试代码块之间,以及代码块与构造函数之间的执行顺序。执行结果如下:
在parentTest()
中 Parent 实例化了两次。从上面的执行结果来看:
- 静态代码块执行了一次。众所周知,是类在初始化的时候执行的,也只执行这一次。
- 非静态代码块执行了两次,而 Parent 实例化了两次。则非静态代码块是在类被实例化的时候执行的,类每实例化一次,则非静态代码块执行一次
- 两种代码块的执行顺序都在构造函数之前。但是静态代码块在非静态之前。
执行
image.pngchildrenTest()
,测试在继承情况下,代码块,构造函数间的执行顺序。执行结果如下:
在childrenTest()
中,Children 实例化了两次。从上面的执行结果看:
- 不管是父类还是子类,静态代码块优先执行。
- 在所有的静态代码块执行完后,执行父类相关的代码。先执行父类非静态代码块,再执行父类构造方法;之后执行子类非静态代码块,再执行子类构造方法
结论
- 静态代码块是在类被加载的时候(即初始化)去执行,且只执行一次
- 非静态代码块是在类被实例化的时候执行。每被实例化一次,就会被执行一次。
- 在无继承的情况下:执行顺序为:静态代码块 ——> 非静态代码块 ——> 构造函数
- 在有继承的情况下:执行顺序为:父类,子类静态方法 ——> 父类非静态代码块、构造函数 ——> 子类非静态代码块、构造函数
网友评论