每天学一点Thinking in java: 16 静态数据初始化

静态数据初始化

无论创建多少对象,static都只有那么一片存储空间。不能对本地变量使用static关键字,只能对字段使用。如果静态的字段是原始类型(primitive)且没有被初始化,则该静态字段获得该类型的标准初始值。如果是某个对象的句柄,则默认初始值是null。正常初始化,和非静态字段一样。

static何时初始化,见下例:

//: initialization/StaticInitialization.java 
// Specifying initial values in a class definition. 
import static net.mindview.util.Print.*; 
class Bowl { 
	Bowl(int marker) { 
		print("Bowl(" + marker + ")"); 
	} 
	void f1(int marker) { 
		print("f1(" + marker + ")"); 
	} 
} 
	
class Table { 
	static Bowl bowl1 = new Bowl(1); 	//1
	Table() { 
		print("Table()");	//3 
		bowl2.f1(1);  //4
	} 
	void f2(int marker) { 
		print("f2(" + marker + ")"); 
	} 
	static Bowl bowl2 = new Bowl(2);   //2
} 

class Cupboard { 
	Bowl bowl3 = new Bowl(3);  //15 11 7
	static Bowl bowl4 = new Bowl(4);  //5
	Cupboard() { 
		print("Cupboard()");  //16 12 8 
		bowl4.f1(2);  //17 13 9 
	} 
	void f3(int marker) { 
		print("f3(" + marker + ")"); 
	} 
	static Bowl bowl5 = new Bowl(5);  //6 
} 

public class StaticInitialization { 
	public static void main(String[] args) { 
		print("Creating new Cupboard() in main");  //10
		new Cupboard(); 
		print("Creating new Cupboard() in main");  //14
		new Cupboard(); 
		table.f2(1);   //18
		cupboard.f3(1);  //19
	} 
	static Table table = new Table(); 
	static Cupboard cupboard = new Cupboard(); 
} 

/* Output: 
Bowl(1) 
Bowl(2) 
Table() 
f1(1) 
Bowl(4) 
Bowl(5) 
Bowl(3) 
Cupboard() 
f1(2) 
Creating new Cupboard() in main 
Bowl(3) 
Cupboard() 
f1(2) 
Creating new Cupboard() in main 
Bowl(3) 
Cupboard() 
f1(2) 
f2(1) 
f3(1) 
*///:~

从结果可以看出,static初始化只在需要时进行。只有在创建了第一个Table对象(或第一次访问static时),才会初始化static。在这之后,static对象不会重新初始化(reinitialized)。
初始化的顺序是先static对象(如果没有在之前创建对象时初始化),再是非static对象

显式static初始化

Java允许我们将其他static初始化工作划分到类内一个特殊的“static构建从句(static clause)”(有时也叫作“静态块”(static block))里,例如:

//: initialization/Spoon.java 
public class Spoon { 
	static int i; 
	static { 
		i = 47; 
	} 
} ///:~

尽管看起来像是一个方法,但它实际只是一个static关键字,后面跟随一个方法主体
与其他static初始化一样,这段代码仅执行一次——首次生成那个类的一个对象时,或者首次访问属于那个类的一个static成员时(即便从未生成过那个类的对象)。例如:

class Cups { 
	static Cup cup1; 
	static Cup cup2; 
	static { 
		cup1 = new Cup(1); 
		cup2 = new Cup(2); 
	} 
}

非静态实例初始化(Non-static instance initialization)

针对每个对象的非静态变量的初始化,Java 1.1提供了一种类似的语法格式。下面是一个例子:

public class Mugs {
	Mug c1;
	Mug c2;
	{
		c1 = new Mug(1);
		c2 = new Mug(2);
	}
	System.out.println("c1 & c2 initialized");
}

看起来与静态初始化从句极其相似,只是static关键字从里面消失了。为支持对“匿名内部类”的初始化,必须采用这一语法格式

你可能感兴趣的:(每天学一点Thinking,in,java)