14K的小短腿

导航

Chapter5_初始化与清理_构造器初始化

一、构造器初始化的基本顺序

  在使用构造器进行初始化时,最需要注意的是初始化的顺序,这种方法可以给初始化的顺序带来很大的灵活性。看如下的一个例子。

 1 class Window{
 2     Window(int marker){
 3         System.out.println("Window(" + marker + ")");
 4     }
 5 }
 6 
 7 class House{
 8     Window w1 = new Window(1);
 9     House(){
10         System.out.println("House()");
11         w3 = new Window(33);
12     }
13     Window w2 = new Window(2);
14     void f(){
15         System.out.println("f()");
16     }
17     Window w3 = new Window(3);
18 }
19 
20 public class test{
21     public static void main(String args[]){
22         House h = new House();
23         h.f();
24     }
25 }
1 Window(1)
2 Window(2)
3 Window(3)
4 House()
5 Window(33)
6 f()

  从输出中我们可以看出来,初始化的顺序有两点最基本的需要注意:

  (1)成员初始化是默认第一个进行的,由编译器控制执行,发生在调用这个类构造器之前,不能阻止其发生。

  (2)变量定义的先后顺序决定了初始化的顺序,即使这些变量定义散布在方法定义之间,变量的初始化仍会在任何方法被调用之前执行。

 

二、静态数据的初始化

   先看一个例子。

 1 class Bowl{
 2     Bowl(int marker){
 3         System.out.println("Bowl(" + marker + ")");
 4     }
 5     void f1(int marker){
 6         System.out.println("f1(" + marker + ")");
 7     }
 8 }
 9 
10 class Table{
11     static Bowl bowl1 = new Bowl(1);
12     Table(){
13         System.out.println("Table()");
14         bowl2.f1(1);
15     }
16     void f2(int marker){
17         System.out.println("f2(" + marker + ")");
18     }
19     static Bowl bowl2 = new Bowl(2);
20 }
21 
22 class Cupboard{
23     Bowl bowl3 = new Bowl(3);
24     static Bowl bowl4 = new Bowl(4);
25     Cupboard(){
26         System.out.println("Cupborad()");
27         bowl4.f1(2);
28     }
29     void f3(int marker){
30         System.out.println("f3(" + marker + ")");
31     }
32     static Bowl bowl5 = new Bowl(5);
33 }
34 
35 public class test{
36     public static void main(String args[]){
37         System.out.println("creating new cupboard() in main");
38         new Cupboard();
39         System.out.println("creating new cupboard() in main");
40         new Cupboard();
41         table.f2(1);
42         cupboard.f3(1);
43     }
44     static Table table = new Table();
45     static Cupboard cupboard = new Cupboard();
46 }
Bowl(1)
Bowl(2)
Table()
f1(1)
Bowl(4)
Bowl(5)
Bowl(3)
Cupborad()
f1(2)
creating new cupboard() in main
Bowl(3)
Cupborad()
f1(2)
creating new cupboard() in main
Bowl(3)
Cupborad()
f1(2)
f2(1)
f3(1)

  从输出可以看出来当有静态成员变量存在时,初始化的顺序是,先对静态的成员变量进行顺序初始化,再对非静态的成员变量进行顺序初始化,需要注意的是,由于静态变量是一块共享的内存区域,所以某个类的静态变量只会被初始化一次。

  书上总结了创建一个对象的编译器的详细过程(假设类为dog):

  (1)由于构造器是静态方法,当首次创建类型为Dog的对象时,或者首次访问静态域时,java解释器首先会查找类路径,定位dog.class文件。

  (2)首次加载dog.class,然后执行一次静态初始化的动作。

  (3)用new dog()创建对象时,先在堆上给dog分配足够的内存空间。

  (4)将这块存储空间清零,会将dog中的所有成员变量变为默认值。

  (5)执行出现于字段定义处的初始化动作。

  (6)执行构造器。

 

posted on 2017-08-14 17:43  14K的小短腿  阅读(173)  评论(0编辑  收藏  举报