我知道有几种方法可以在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()
方法是私有的,我知道不同的可见性可能导致初始化错误(当子类化时),这不是重点。
答案 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