亲,我们的名字好像哦:lol
说下自己的理解:
我记得《thinking in java》原话:无论创建多少对象,static数据都只只用一份存储区域。static关键字不能应用于局部变量,因此他只能这用于域。如果一个域是基本类型,并且没有给它初始化,那么他会默认为基本类型的标准初始值;如果是一个引用,那么他会默认为初始值null。- //: 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);
- Table() {
- print("Table()");
- bowl2.f1(1);
- }
- void f2(int marker) {
- print("f2(" + marker + ")");
- }
- static Bowl bowl2 = new Bowl(2);
- }
-
- class Cupboard {
- Bowl bowl3 = new Bowl(3);
- static Bowl bowl4 = new Bowl(4);
- Cupboard() {
- print("Cupboard()");
- bowl4.f1(2);
- }
- void f3(int marker) {
- print("f3(" + marker + ")");
- }
- static Bowl bowl5 = new Bowl(5);
- }
-
- public class StaticInitialization {
- public static void main(String[] args) {
- print("Creating new Cupboard() in main");
- new Cupboard();
- print("Creating new Cupboard() in main");
- new Cupboard();
- table.f2(1);
- cupboard.f3(1);
- }
- 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)
- */
复制代码 Bowl类使得看到类的创建,而Table类和Cupboard类在他们的类中分别定义了Bowl类的static成员对象。注意在定义静态数据成员之前,Cupboard类先定义了一个Bowl类型的非静态成员bowl3。
由此可见静态数据只有在必要时才进行初始化。如果不创建Table对象,也不引用Talbe的bowl1和bowl2,那么Talbe的bowl1和bowl2永远都不会被创建。只有在第一个Talbe被创建时或第一次访问其中的Bowl类型的静态成员时,他们才会被初始化。此后静态数据不会在被初始化。
通过上面的事例可以总结:在创建一个类时,初始化的顺序是先是静态数据,并且仅初始化一次(如果它们尚未因前面对象的创建或某些动作的执行未被初始化),而后是非静态数据(每次在创建时都会初始化),然后是构造函数。
另外直接用类名调用静态数据和静态方法时,这个类中的所以静态成员都会被初始化(非static成员不会被初始化),前提是他们从未被初始化过。
从结果中可以观察到这一点。要执行main()(stati方法),必须加载StaticInitialization类,然后是StaticInitialization 类中的sataic成员table 和cupboard 的初始化,这将导致Tabel和Cupboard 类中的静态数据也会被初始化。这样在main()未开始之前,所有对象已经被初始化。然而在main()方法在执行创建Cupboard 类对象时,Cupboard 中的static数据不会再被初始化,因为static数据已经在main()之前已经被第一次初始化。 |