2011-10-07 34 views
0

這個Java程序簡單,充滿意見的,所以你可以fast.however理解,爲什麼在構建員工[1],該計劃先去聲明:java的構造爲了

this("Employee #" + nextId, s); 

然後去對象初始化塊,然後回到說法,怎麼confusion.why不是第一次使用對象初始化塊

import java.util.*; 

public class ConstructorTest 
{ 
    public static void main(String[] args) 
    { 
     // fill the staff array with three Employee objects 
     Employee[] staff = new Employee[3]; 

     staff[0] = new Employee("Harry", 40000); 
     staff[1] = new Employee(60000); 
     staff[2] = new Employee(); 

     // print out information about all Employee objects 
     for (Employee e : staff) 
     System.out.println("name=" + e.getName() 
      + ",id=" + e.getId() 
      + ",salary=" + e.getSalary()); 
    } 
} 

class Employee 
{ 
    // three overloaded constructors 
    public Employee(String n, double s) 
    { 
     name = n; 
     salary = s; 
    } 

    public Employee(double s) 
    { 
     // calls the Employee(String, double) constructor 
     this("Employee #" + nextId, s); 
    } 

    // the default constructor 
    public Employee() 
    { 
     // name initialized to ""--see below 
     // salary not explicitly set--initialized to 0 
     // id initialized in initialization block 
    } 

    public String getName() 
    { 
     return name; 
    } 

    public double getSalary() 
    { 
     return salary; 
    } 

    public int getId() 
    { 
     return id; 
    } 

    private static int nextId; 

    private int id; 
    private String name = ""; // instance field initialization 
    private double salary; 

    // static initialization block 
    static 
    { 
     Random generator = new Random(); 
     // set nextId to a random number between 0 and 9999 
     nextId = generator.nextInt(10000); 
    } 

    // object initialization block 
    { 
     id = nextId; 
     nextId++; 
    } 
} 
+2

什麼問題? – MasterCassim

+0

聽起來就像你在問爲什麼'this'語句在實例初始化塊之前執行。那是對的嗎? –

回答

4

因爲this("Employee #" + nextId, s);包括對父類的構造的隱式調用,這當然必須執行之前的初始化塊子類。

使用實例初始值設定器通常是一個壞主意,因爲它們不是衆所周知的,除了構造函數之外不能做任何事情,混合兩者都會導致混淆。

+0

thx.this真的是一個壞主意。 – huateng

1

這是繼節8.8.7.1 of the JLS指定的順序:

(最終兩顆子彈)

設C是類被實例化,令S是C的直接超類,讓我是實例正在創建。一個明確的構造函數調用進行的評價如下:

  • 首先,如果構造函數調用語句是一個父類的構造函數調用, (剪斷,因爲它不是在我們的例子)
  • 接下來,構造函數被調用。最後,如果構造函數調用語句是超類構造函數調用,並且構造函數調用語句正常完成,那麼將執行C的所有實例變量初始值設定項和C的所有實例初始值設定項。 (Snip)另一個構造函數調用不執行這個額外的隱式操作。

因此實例初始化執行超類後立即被稱爲 - 這是從public Employee(String n, double s)(隱含的)。這應該在執行該雙參數構造函數的主體之前發生。

0

不確定實際問題是什麼,這有點令人困惑。初始化的順序(靜態,對象,構造函數)是預定義的,並且與它們在代碼中出現的順序無關。至於一般風格,我通常不鼓勵使用對象初始化塊。這是一個非常常見的錯誤來源,它使異常處理更加複雜,並且很難調試。另外,它不是一個很常見的模式,因此開發人員在分析錯誤時往往會錯過尋找它。

0

Java編譯器必須確保從每個構造函數調用對象初始化塊中的代碼。對於大多數構造函數,它通過在隱式或顯式調用super()之後將代碼插入構造函數來完成此操作。對於以this()開頭的編譯器,首先不隱式調用super() - 另一個構造函數處理它。其次,在這樣的構造函數中,根本不能插入對象初始化塊,因爲當調用第二個構造函數時,代碼將被拾取。因此,this()呼叫是發生的第一件事。