重温经典《Thinking in java》第四版之第五章 初始化与清理(三十三)

简介: 重温经典《Thinking in java》第四版之第五章 初始化与清理(三十三)

“5.7.2 静态数据的初始化”这一小节介绍了类中静态数据成员的初始化方法。众所周知,无论创建多少对象,静态数据都只占用一份存储区域。static关键字不能应用于局部变量,它只能作用于域,比如类、数据成员和行为方法。如果一个域是静态的基本类型域,且也没有对它进行初始化,那么它就会获得基本类型的标准初值;如果它是一个对象引用,那么它的默认初始化值就是null。

如果想在定义处进行初始化,采取的方法跟非静态数据没什么不同,下面看一个例子:

importstaticnet.mindview.util.Print.*; 
classBowl { 
Bowl(intmarker) { 
print("Bowl("+marker+")"); 
    } 
voidf1(intmarker) { 
print("f1("+marker+")"); 
    } 
} 
classTable { 
staticBowlbowl1=newBowl(1); 
Table() { 
print("Table()"); 
bowl2.f1(1); 
    } 
voidf2(intmarker) { 
print("f2("+marker+")"); 
    } 
staticBowlbowl2=newBowl(2); 
} 
classCupboard { 
Bowlbowl3=newBowl(3); 
staticBowlbowl4=newBowl(4); 
Cupboard() { 
print("Cupboard()"); 
bowl4.f1(2); 
    } 
voidf3(intmarker) { 
print("f3("+marker+")"); 
    } 
staticBowlbowl5=newBowl(5); 
} 
publicclassStaticInitialization { 
publicstaticvoidmain(String[] args) { 
print("Creating new Cupboard() in main"); 
newCupboard(); 
print("Creating new Cupboard() in main"); 
newCupboard(); 
table.f2(1); 
cupboard.f3(1); 
    } 
staticTabletable=newTable(); 
staticCupboardcupboard=newCupboard(); 
}

/* 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)

*///:~

由输出可见,静态初始化只有在必要时刻才会进行。如果不创建Table对象,也不引用Table.b1或Table.b2,那么敬爱的Bowl b1和b2永远都不会被创建。只有在第一个Table对象被创建(或者第一次访问静态数据)的时候,他们才会被初始化。此后,静态对象不会再次被初始化,即只初始化一次。初始化的顺序是先静态对象,而后是非静态对象。

Java允许将多个静态初始化动作组织成一个特殊的“静态子句”(有时也叫做“静态块”)。就像下面这样:

publicclassSpoon { 
staticinti; 
static { 
i=47; 
    } 
}

尽管上面的代码看起来像个方法,但它实际只是一段跟在static关键字后面的代码。与其他静态初始化动作一样,这段代码仅执行一次:当首次生成这个类的对象或首次访问属于那个类的静态域时。例如:

importstaticnet.mindview.util.Print.*; 
classCup { 
Cup(intmarker) { 
print("Cup("+marker+")"); 
    } 
voidf(intmarker) { 
print("f("+marker+")"); 
    } 
} 
classCups { 
staticCupcup1; 
staticCupcup2; 
static { 
cup1=newCup(1); 
cup2=newCup(2); 
    } 
Cups() { 
print("Cups()"); 
    } 
} 
publicclassExplicitStatic { 
publicstaticvoidmain(String[] args) { 
print("Inside main()"); 
Cups.cup1.f(99); // (1)     } 
// static Cups cups1 = new Cups(); // (2) // static Cups cups2 = new Cups(); // (2) }

/* Output:

Inside main()

Cup(1)

Cup(2)

f(99)

*///:~

标为(1)和(2)中无论哪一行被运行,Cups的静态初始化动作都会得到执行。此外,不管运行几行,静态初始化动作只会运行一次,可以通过运行代码看到这种现象。

“5.7.2 非静态实例初始化”中提到了一种用来初始化每一个对象的非静态变量方法,该方法一般使用的不多,跟静态变量初始化唯一的区别就是省略了static关键词,但是初始化原理截然不同,即对象每次被实例化都会执行一次,而静态变量只会执行一次。例如:

importstaticnet.mindview.util.Print.*; 
classMug { 
Mug(intmarker) { 
print("Mug("+marker+")"); 
    } 
voidf(intmarker) { 
print("f("+marker+")"); 
    } 
} 
publicclassMugs { 
Mugmug1; 
Mugmug2; 
    { 
mug1=newMug(1); 
mug2=newMug(2); 
print("mug1 & mug2 initialized"); 
    } 
Mugs() { 
print("Mugs()"); 
    } 
Mugs(inti) { 
print("Mugs(int)"); 
    } 
publicstaticvoidmain(String[] args) { 
print("Inside main()"); 
newMugs(); 
print("new Mugs() completed"); 
newMugs(1); 
print("new Mugs(1) completed"); 
    } 
}

/* Output:

Inside main()

Mug(1)

Mug(2)

mug1 & mug2 initialized

Mugs()

new Mugs() completed

Mug(1)

Mug(2)

mug1 & mug2 initialized

Mugs(int)

new Mugs(1) completed

*///:~

从输出可以看到实例初始化子句是在两个构造器之前执行的。

目录
相关文章
|
2天前
|
NoSQL Java Redis
软件开发常见流程之宝塔初始化安装环境配置,Lam前面不选,直接跳商城,在宝塔内点击软件商城,安Mysql5.7,安java项目管理器,安Ngnix最新版,安Redis
软件开发常见流程之宝塔初始化安装环境配置,Lam前面不选,直接跳商城,在宝塔内点击软件商城,安Mysql5.7,安java项目管理器,安Ngnix最新版,安Redis
|
6天前
|
存储 Java 容器
Java数组的初始化方法
Java数组的初始化方法
|
10天前
|
缓存 并行计算 Java
重温JAVA线程池精髓:Executor、ExecutorService及Executors的源码剖析与应用指南
重温JAVA线程池精髓:Executor、ExecutorService及Executors的源码剖析与应用指南
|
11天前
|
存储 Java
心得经验总结:浅谈Java类中的变量初始化顺序
心得经验总结:浅谈Java类中的变量初始化顺序
10 1
|
11天前
|
存储 监控 Java
深入理解Java虚拟机-类加载连接和初始化解析
深入理解Java虚拟机-类加载连接和初始化解析
|
13天前
|
安全 Java 程序员
在Java中,finalization是一种机制,允许对象在被垃圾收集器回收之前执行一些清理操作。
【6月更文挑战第24天】Java中的finalization机制允许对象在被垃圾收集前执行清理,以释放系统资源或处理敏感信息。`finalize()`方法用于定义此类操作,但它不是可靠的资源管理策略,因为调用时机不确定且可能影响性能。尽管可用于清理外部资源或作为保护措施,但应避免依赖finalization,而应优先采用手动资源管理,遵循“创建者负责”原则。
13 1
|
23天前
|
Java
Java 基础深度解析:变量与常量的声明、赋值与初始化的权威指南
【6月更文挑战第14天】Java编程中的变量和常量是基础关键。声明变量如`int age;`,赋值与初始化可在声明时或后续代码中完成。常量用`final`修饰,如`public static final double PI = 3.14159;`,且只能赋值一次。变量命名应具描述性,常量值设定后尽量不变,注重代码的可读性和可维护性。熟练掌握这些将有助于编写高质量Java程序。
|
24天前
|
Java 编译器 API
java.lang.NoClassDefFoundError:无法初始化类XXX
java.lang.NoClassDefFoundError:无法初始化类XXX
15 0
|
2月前
|
Java 编译器
Java语言中的初始化:深入探索
Java语言中的初始化:深入探索
|
2月前
|
存储 Java
Java二维数组的初始化技术详解
Java二维数组的初始化技术详解
31 0