2010-03-31 94 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()是微不足道的,所以我不会在这里使用它,但如果这实际上有大量的工作,那么它可能是有用的。您也可以从构造函数传入参数。