Init块VS init()在构造函数中调用的私有方法

时间:2014-03-21 16:38:59

标签: java initialization

我知道有几种方法可以在Java中创建实例时初始化东西,但我对以下两种可能性之间的区别感兴趣。

案例1:

{
    // common init code for all constructors
}

public MyType() {
    super();
    // specific init code
}

public MyType(Object arg) {
    super(arg);
    // specific init code
}

案例2:

public MyType() {
    super();
    init();
    // specific init code
}

public MyType(Object arg) {
    super(arg);
    init();
    // specific init code
}

private void init() {
    // common init code for all constructors
}

我相信这2个案例在代码方面是等价的。我认为第一个更快,因为减少了1个方法调用,但另一方面,对于不太了解初始化的人来说可能会让人感到困惑。

我错过了另一个可能导致我们选择其中一个的差异吗? 我最好使用哪个选项?

注意: init() 方法是私有的,我知道不同的可见性可能导致初始化错误(当子类化时),这不是重点。

2 个答案:

答案 0 :(得分:1)

  

也许第一个更快,因为少了一个方法调用,但我认为它的可读性较差。

我甚至不考虑这里的效率,因为它只会使方法调用产生微小的差异。但为什么你认为它的可读性较差?它是Java语言的一个众所周知的特性。

  

我最好使用哪个选项?

第一种方法的好处是,您可以编写更少的代码。并且在第二种方法中存在轻微的人为错误的可能性。通常,当您希望在每个构造函数中完成初始化时,您将使用实例初始化程序块。这样可以避免在所有构造函数中显式编写相同的代码。使用另一种方法,您必须记住从所有构造函数中调用init()方法。

但是如果你想让一些初始化成为某个构造函数的一部分,那么第二种方法可能会很有用。但这是非常罕见的IMO。

答案 1 :(得分:0)

简而言之,第一种情况下的init代码将在构造函数之前调用,在第二种情况下调用。 看看这个question

一般规则是避免像theese这样的结构,而是使用static-factory-methods

顺序可能很重要然后调用this()而不是super(): 考虑代码:

public class InitOrderTest {
static class Super {
    Super() {
        System.out.println("Super constructor");
    }
}
static class Puper extends Super {
    {
        System.out.println("Code block");
    }
    Puper() {
        this("Self constructor");
        init();
    }

    public Puper(String inner) {
        System.out.println(inner);
    }

    private void init() {
        System.out.println("Init call");
    }
}
public static void main(String[] args) {
   new Puper();
}

}

打印:

Super constructor
Code block
Self constructor
Init call