Static{}静态代码块的使用
static{}静态代码块在类的加载时执行,并且只执行一次,且在main方法之前执行。一个类中可以有多个静态代码块,执行顺序自上而下。一个静态代码块只能访问该静态代码块之前的静态变量。
static{}静态代码块在类初次被加载的时候被执行且只会被执行一次,所以可以起到优化程序性能的作用。
静态代码块的语法:
//静态代码块
static
{
//Java程序
}
实例语句块的使用
除了static{}静态代码之外,还有一种语句块叫做实例语句块。
顾名思义,就是在实例化对象时执行,并不是在类加载时执行。
实例语句块的具体执行时间是在实例化对象时的构造函数之前执行的。
实例语句块的语法:
//实例语句块
{
//Java程序
}
java程序初始化顺序
在java语言中,当时实例化对象时,对象所在类的所有成员首先要进行初始化,只有当所有类成员完成初始化后,才会调用对象所在的构造函数创建对象。
Java程序的初始化一般遵循一下三个原则:
- 静态对象(变量)、非静态对象(变量)
- 父类优于子类进行初始化。
- 按照成员变量定义的顺序进行初始化。
java程序的初始化工作可以在许多不同的代码块中完成,例如:静态代码块、实例语句块、构造函数等。
普通类的执行顺序
普通类的执行顺序为:静态代码块->实例语句块->构造函数。
【示例】普通类的执行顺序
(1)创建普通类
package com.jamison.initalizationOrder;
/**
* 普通类的执行顺序为:静态代码块 → 实例语句块 → 构造函数。
* @author jamison
*/
public class MyClass {
//静态代码块
static {
System.out.println("静态代码块");
}
//实例语句块
{
System.out.println("实例语句块");
}
/**
* 构造函数
*/
public MyClass() {
System.out.println("构造函数");
}
}
(2)执行方法
package com.jamison.initalizationOrder;
/**
* @author jamison
*/
public class TestMyClass {
public static void main(String[] args) {
MyClass myClass = new MyClass();
}
}
/**
* result:
* 静态代码块
* 实例语句块
* 构造函数
*/
继承类的执行顺序
继承类的执行顺序为:父类静态代码块->子类静态代码块->父类实例语句块->父类构造函数->子类实例语句块->子类构造函数。
【实例】继承类的执行顺序
(1)创建父类
package com.jamison.initalizationOrder;
/**
* @author jamison
*/
public class Parent {
//静态代码块
static {
System.out.println("父类静态代码块");
}
//实例语句块
{
System.out.println("父类实例语句块");
}
/**
* 构造函数
*/
public Parent() {
System.out.println("父类构造函数");
}
}
(2)创建子类
package com.jamison.initalizationOrder;
/**
* @author jamison
*/
public class Child extends Parent{
//静态代码块
static {
System.out.println("子类静态代码块");
}
//实例语句块
{
System.out.println("子类实例语句块");
}
/**
* 构造函数
*/
public Child() {
System.out.println("子类构造函数");
}
}
(3)执行方法
package com.jamison.initalizationOrder;
/**
* 继承类的执行顺序为:父类静态代码块 → 子类静态代码块 → 父类实例语句块 → 父类构造函数 → 子类实例语句块 → 子类构造函数。
* @author jamison
*/
public class TestParent {
public static void main(String[] args) {
Child child = new Child();
}
}
/**
* result:
* 父类静态代码块
* 子类静态代码块
* 父类实例语句块
* 父类构造函数
* 子类实例语句块
* 子类构造函数
*/
成员变量初始化的优先级
这里需要注意的是,(静态)非静态成员域在定义时初始化和(静态)非静态块中初始化的优先级是平级的,也就是说按照从上到下初始化,最后一次初始化为最终值(不包括非静态的成员域在构造器中初始化)。所以在(静态)非静态代码块中初始化的域甚至能在该域声明的上方,因为分配存储空间在初始化之前就完成了。
【示例】(静态)非静态中成员变量初始化的优先级。
package com.jamison.initalizationOrder;
/**
*这里需要注意的是,(静态)非静态成员域在定义时初始化和(静态)非静态块中初始化的优先级是平级的,也就是说按照从上到下初始化,最后一次初始化为最终的值(不包括非静态的成员域在构造器中初始化)。所以在(静态)非静态块中初始化的域甚至能在该域声明的上方,因为分配存储空间在初始化之前就完成了。
* @author jamison
*/
public class TestStatic {
static {
a = 1;
}
static int a = 3;
static {
b = 5;
}
static int b = 7;
public static void main(String[] args) {
System.out.println("初始化变量后的a,b值");
System.out.println(a);
System.out.println(b);
}
/**
* 初始化变量后的a,b值
* 3
* 7
*/
}