static block and non-static block(constructor block)
想来想去,先来一题比较好
public class Foo {
public static void main(String[] args) {
Baz.testAsserts();
Baz.testAsserts();
// Will execute after Baz is initialized.
}
}
class Bar {
static {
Baz.testAsserts();
// Will execute before Baz is initialized!
}
}
class Baz extends Bar {
static int x = 1;
static void testAsserts() {
System.out.println("x is " + x);
x=x+2;
}
}
- 输出结果
x is 0
x is 1
x is 3
- 分析
- Invoking Baz.testAsserts() cause Baz to be initialized
- default value int x=0;
- Before Baz initialize , Bar must be initialized
- Bar's static initializer again invoking Baz.testAsserts()
- so x is 0 , then x+2 , x=2
- go on initializing Baz , init x = 1;
- Invoking Baz.testAsserts() x = 1 , so x is 1;
Java类初始化顺序
父类静态变量 ——>父类静态代码块——>子类静态代码块——>父类非静态变量 ——>
父类非静态代码块——>父类构造函数 ——>子类非静态变量——>子类非静态代码块——>
子类构造函数
非静态代码块 non-static block(constructor block)
class A {
int x ;
//block num 1
{
x = 1;
System.out.println("block num 1, x is " + x);
}
A() {
x = 3;
System.out.println("constructor block x is " + x);
}
//block num 2
{
x = 2;
System.out.println("block num 2, x is " + x);
}
}
public class Non_staticBlock {
public static void main(String[] args) {
String newLine = System.getProperty("line.separator");
System.out.println("====first time instantiate ====" + newLine);
new A();
System.out.println(" \n====second time instantiate ====" + newLine);
new A();
}
}
- 输出结果、顺序
====first time instantiate ====
block num 1, x is 1
block num 2, x is 2
constructor x is 3====second time instantiate ====
block num 1, x is 1
block num 2, x is 2
constructor x is 3
- 非静态代码块被java编译器拷贝到了构造块内,所以称为"constructor block"也是可以的,所以每次 new 构造函数也都执行
- .class 文件如下, 非静态代码块被java编译器拷贝到了构造块内.
class A {
int x = 1;
A() {
System.out.println("block num 1, x is " + this.x);
this.x = 2;
System.out.println("block num 2, x is " + this.x);
this.x = 3;
System.out.println("constructor x is " + this.x);
}
}
静态代码块 static block
class AA {
AA() {
x = 3;
System.out.println("constructor x is " + x);
}
static int x = 1;
//block num 1
static {
System.out.println("static block num 1 , x is " + x);
}
//block num 2
static {
x = 2;
System.out.println("static block num 2 , x is " + x);
}
static void print() {
System.out.println("static method");
}
}
public class StaticBlock {
static {
System.out.println("==== first ====");
}
public static void main(String[] args) {
String newLine = System.getProperty("line.separator");
System.out.println("====AA class init ====" + newLine);
// class init
AA.print();
System.out.println(" \n====fisrt time instantiate AA====" + newLine);
new AA();
System.out.println(" \n====sencond time instantiate AA====" + newLine);
new AA();
}
}
- 输出结果、顺序
==== first ====
====AA class init ====static block num 1 , x is 1
static block num 2 , x is 2
static method
==== first time instantiate AA ====constructor x is 3
==== second time instantiate AA ====
constructor x is 3
- 由于JVM在加载类时会执行静态代码块,且只会执行一次. 本例静态引用
AA.print();
触发类初始化 -
静态代码块先于主方法执行,本例优先打印
first
- 更多内容搜索jvm类加载
- .class 文件如下
class AA {
static int x = 1;
AA() {
x = 3;
System.out.println("constructor x is " + x);
}
static void print() {
System.out.println("static method");
}
static {
System.out.println("static block num 1 , x is " + x);
x = 2;
System.out.println("static block num 2 , x is " + x);
}
}
联合看一下
class AAA {
int x;
//block num 1
{
x = 1;
System.out.println("non-static block num 1 x is " + x);
}
AAA() {
x = 3;
System.out.println("constructor x is " + x);
}
//block num 2
{
x = 2;
System.out.println("non-static block num 2 x is " + x);
}
// The static block only gets called once,when the class itself is initialized,
// no matter how many objects of that type you create
static {
System.out.println("static block");
}
//Gets called every time an instance of the class is constructed.
//the non-static block is actually copied by the Java compiler into every constructor the class has (source).
//So it is still the constructor's job to initialize fields.
//to understand "actually " , find the result in the .class file of A.class
{
System.out.println("non-static block");
}
}
public class BlockSample {
public static void main(String[] args) {
String newLine = System.getProperty("line.separator");
System.out.println("====first time instantiate AAA ====" + newLine);
new AAA();
System.out.println(" \n====second time instantiate AAA ====" + newLine);
new AAA();
}
}
- 输出结果、顺序
====first time instantiate AAA ====
static block
non-static block num 1 x is 1
non-static block num 2 x is 2
non-static block
constructor x is 3====second time instantiate AAA ====
non-static block num 1 x is 1
non-static block num 2 x is 2
non-static block
constructor x is 3
- .class 文件
class AAA {
int x = 1;
AAA() {
System.out.println("non-static block num 1 x is " + this.x);
this.x = 2;
System.out.println("non-static block num 2 x is " + this.x);
System.out.println("non-static block");
this.x = 3;
System.out.println("constructor x is " + this.x);
}
static {
System.out.println("static block");
}
}