浮躁的技术之路  
Self Control!!!

1) 成员初始化
由于任何方法都可以初始化或使用那个数据,所以在正式使用数据前,若还是强迫程序员将其一一初始化成一个适当的值,就可能不够实际。因此,一个类的所有primitive数据成员都会保证获得一个缺省值,都是0,不同的数据类型意义不一样。当然,句柄会或得null值。

2) 定义初始化

一个直接的做法是在定义数据成员的同时也为其赋值,并且是在构造函数之前

class Measurement {
   
boolean b = true;
   
char c = 'x';
   
int i = 47;   
}


也可以用相同的方法初始化对象

class Measurement {
   Depth o 
= new Depth();
}


可以调用一个方法进行初始化

class CInit {
   
int i = f();
}


当然这个方法也可以使用参数

class CInit {
   
int i =f(); int k = g(i);
}


但是那些参数不能是尚未初始化的其他数据成员。

class CInitWrong {
   
int j = g(i); int i = f();
}


3) 初始化顺序
在一个类里,初始化的顺序是由变量在类内的定义顺序决定的。即使变量定义大量遍布于方法定义的中间,那些变量仍然会在调用任何方法之前得到初始化,当然在构造函数之前。

class Tag {
    Tag(
int marker) {
        System.out.println(
"Tag(" + marker + ")");
    }
}

class Card {
    Tag t1 
= new Tag(1); // Before constructor

    Card() {
        
//Indicate we're in the constructor:
        System.out.println("Card()");
        t3 
= new Tag(33); //Re-initialize t3
    }

    Tag t2 
= new Tag(2); //After constructor

    
void f() {
        System.out.println(
"f()");
    }

    Tag t3 
= new Tag(3); //At end
}

public class OrderOfInitialization {
    
public static void main(String[] args) {
        Card t 
= new Card();
        t.f();
//Shows that construction is done
    }
}


4) 静态数据初始化
Java是相对比较纯洁的OOP语言,纯洁度90%,5%的杂质是primitive types,基础数据类型,还有5%就是静态数据。
静态的成员变量,静态的成员函数,属于类,不属于对象。类是规则,是虚的;对象是实体,是实的。根据类来制造对象。所有类的静态变量是共享的!

类Class与类对象。Java程序启动后,JVM制造一个对象空间,里面所有的东西都是对象,Java动态装载需要的类,需要时装载类的定义,这些类的定义在空间里面就是类对象,这些对象用来代表那些类。There is a class named class!静态的成员变量就在类对象里面,因此它在被装载时初始化!

静态数据成员只在这个类的第一个对象要创建的时候初始化。

class Bowl
{
  
public Bowl(int marker)
  {
    System.out.println(
"Bowl(" + marker + ")");
  }
  
void f1(int marker)
  {
    System.out.println(
"f1(" + marker + ")");
  }
}

class Table
{
  
static Bowl bowl1 = new Bowl(1);//Table 里面还是先初始化这里,最先输出 Bowl(1)---1
    
  
public Table() //两个静态域初始化完成后,是构造函数了
  {
    System.out.println(
"Table()");//输出 Table()---3
    bowl2.f1(1);  //当然该这里了,bowl2已经有了,输出f1(1)---4
  }
  
void f2(int marker)
  {
    System.out.println(
"f2(" + marker + ")");
  }
    
  
static Bowl bowl2 = new Bowl(2);//Bowl(1)完了,该这里了,初始化Bowl(2),输出 Bowl(2)---2
}

class Cupboard
{
  Bowl bowl3 
= new Bowl(3);//终于该我了,下面两个静态的,很牛嘛。输出 Bowl(3),---7;从10又回来了,这下没下面两个什么事情了,因为,是静态的嘛,呵呵,照样输出 Bowl(3),---11;懒得说了,---15

  
static Bowl bowl4 = new Bowl(4);//同样的,先初始化静态域,输出 Bowl(4),上面的要等一等了,谁让你不是静态域呢?:)---5

  
public Cupboard()//7初始化完毕,构造函数开始;从11又来了;
  {
    System.out.println(
"Cupboard()");//简简单单的输出,哪有你们上面的那么复杂---8;依旧简简单单的输出 ---12;---16
    bowl4.f1(2);//bowl4 已经在了,调用它的f1()方法,输出f1(2)---9;从上面来的,bowl4 仍然在,继续输出f1(2)---13;---17
  }
  
void f3(int marker)
  {
     System.out.println(
"f3(" + marker + ")");
  }
  
  
static Bowl bowl5 = new Bowl(5);//bowl3,你还是再等等吧,我先来,我也是静态域,虽然我在下面,没办法~~~ ---6
}

class StaticInitialization
{
  
public static void main(String[] args)//从这里开始~~,不过别急,先初始化下面的静态域 table 和 Cupboard。 
  {
    System.out.println(
"Creating new Cupboard() in main");//从9开始才真正的到这里,虽然在 main 里,好惨~~ ---10
    new Cupboard(); // new 了一个对象
    System.out.println("Creating new Cupboard() in main");//从13过来,又来~~你烦不烦~~,继续输出---14
    new Cupboard(); //又 new 了一个对象,我为什么要说 又..
    
    table.f2(
1);//从17回来,f2(1)---18
    cupboard.f3(1);//f3(1),---19完
  }
  
static Table table = new Table();//所以说,实际上是从这里开始先加载 Table 类
  static Cupboard cupboard = new Cupboard();//4完后,该这里了
}


总结一下:
1. 类型为Dog的一个对象首次创建时,或者Dog类的静态方法/数据首次访问时,Java解释器必须找到Dog.class。
2. 找到Dog.class后,它的所有的静态初始化模块都会运行。因此,静态初始化仅发生一次。
3. 创建一个new Dog()时,new语句首先会在堆里分配一个足够的空间。
4. 这个空间将会被清除为零,因此Dog中所有的数据成员都得到了缺省值。
5. 执行定义初始化。
6. 执行构造函数。

 

posted on 2009-01-21 00:34  马里奥  阅读(264)  评论(0编辑  收藏  举报