繁体   English   中英

如何避免代码重复初始化最终属性?

[英]How to avoid code repetition initializing final properties?

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);
}

}

编译器将所有初始值设定项添加到每个构造函数的开头。 这包括:

  • 实例变量初始化
  • 初始化块{ .. }

因此,您不必将它包含在任何地方,只需将其作为实例变量初始化:

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

或者在初始化块中:

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

当然,在这个精确的例子中,你应该使该字段static

这是您的代码,有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

做就是了:

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

见: JLS 8.3.2。 字段的初始化

另请参阅: JLS 12.5为执行顺序创建新类实例

如果每次都以相同的方式初始化它们,则可以将代码放在构造函数之外。 Java允许您这样做:

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

您还可以使用除无参数之外的所有构造函数调用无参数构造函数。 例如:

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

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

另外,如果初始化很复杂并且您必须在构造期间执行此操作,则提供静态方法以返回结果,如下所示:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM