2010-03-31 93 views
4
public class Code{ 

//many properties 
//... 

final String NEWLINE;// ohh a final property! 

void creation() //this method is for avoid repetition of code 
{   

    //final initialization can't be put here =(

    Source= new StringBuffer(); 

    //many other commons new's .. 
    //... 
} 

Code() 
{ 
    NEWLINE = System.getProperty("line.separator"); 
    creation(); 
} 

Code(String name, int numberr) 
{ 
    NEWLINE = System.getProperty("line.separator"); 
    creation(); 

    name=new Someting(name); 
    number = new Magic(number); 
} 

}如何避免代碼重複初始化最終屬性?

+1

+1「// ohh最後的屬性!「和一個有用的Q總體:) – DVK 2010-03-31 19:31:20

+2

爲什麼你的NEWLINE是一個實例變量?我會聲明類似於這個靜態的。我懷疑line.separator會在JVM實例的生命週期內改變。 – Uri 2010-03-31 20:02:37

回答

6

這是你的代碼,有4種不同的初始化最終變量的方法。

  1. 直列
  2. 匿名初始化塊
  3. 在構造
  4. 初始化調用默認構造明確

所產生的輸出如下所示。

public class Code { 

    // many properties 
    private String name; 
    private String number; 
    // ... 

    // 1. 
    final String NEWLINE_1 = "1" + System.getProperty("line.separator"); 
    final String NEWLINE_2; 
    final String NEWLINE_3; 

    // 2. 
    { 
     System.out.println("initializer block invoked before Constructor"); 

     NEWLINE_2 = "2" + System.getProperty("line.separator"); 
     // final initialization CAN be put here =(

     // Source = new StringBuffer(); 

     // many other commons new's .. 
     // ... 
    } 

    Code() { 
     System.out.println("default constructor"); 
     // NEWLINE_1 = "error";  can't do this 
     // NEWLINE_2 = "error";  can't do this 

     // 3. 
     NEWLINE_3 = "3" + System.getProperty("line.separator"); 
    } 

    Code(String name, int number) { 
     // 4. 
     this(); 
     System.out.println("constructor(name, number)"); 

     name = new String("Someting(name)"); 
     this.number = new String("Magic(number)"); 
    } 

    public static void main(String[] args) { 
     Code code_1 = new Code(); 
     System.out.println(code_1.NEWLINE_1 + ":" + code_1.NEWLINE_2 + ":" + code_1.NEWLINE_3); 

     Code code_2 = new Code("crowne", 2); 
     System.out.println(code_2.NEWLINE_1 + ":" + code_2.NEWLINE_2 + ":" + code_2.NEWLINE_3); 
    } 
} 

initializer block invoked before Constructor 
default constructor 
1 
:2 
:3 

initializer block invoked before Constructor 
default constructor 
constructor(name, number) 
1 
:2 
:3 
1

如果它們每次都以相同的方式初始化,那麼可以將代碼放在構造函數之外。 Java允許你做:

final String NEWLINE = System.getProperty("line.separator"); 

你也可以有比無參數調用一個無參數的構造函數以外的所有構造函數。例如:

Code(String name, int number) 
{ 
    this(); 

    name=new Someting(name); 
    number = new Magic(number); 
} 
6

編譯器將所有初始值設定項添加到每個構造函數的開頭。這包括:

  • 實例變量初始化
  • 初始化塊{ .. }

所以你不必包含這個無處不只是將它放在作爲一個實例變量初始化:

private final String NEWLINE = System.getProperty("line.separator"); 

或在初始化塊中:

{ 
    NEWLINE = System.getProperty("line.separator"); 
} 

當然,在這個精確的例子中,你應該使字段static

1

一個,如果初始化是複雜的,你必須在施工期間做到這一點,提供了一個靜態方法的返回結果,如:

Code() 
{ 
    NEWLINE = newLineValue(); 
    creation(); 
} 

Code(String name, int number) 
{ 
    NEWLINE = newLineValue(); 
    creation(); 

    name = new Something(name); 
    number = new Magic(number); 
} 

private static String newLineValue() 
{ 
    return System.getProperty("line.separator"); 
} 

在這情況下,newLineValue()是微不足道的,所以我不會在這裏使用它,但如果這實際上有大量的工作,那麼它可能是有用的。您也可以從構造函數傳入參數。