2010-01-06 88 views
2

比方说,我有这样的:这两种初始化模式有区别吗?

public class Whatever { 
    private ArrayList<String> myList = new ArrayList<String>(); 
    // more code goes here 
} 

还是让我们说我有这样的:

public class Whatever { 
    private ArrayList<String> myList = null; 

    public Whatever() { 
    myList = new ArrayList<String>(); 
    } 
} 

什么的myList这两个initialisations之间的区别?假设第一个变体是否是错误的?

+1

相关的说明,这是最好的事情: 私人列表 myList中=新的ArrayList () – sateesh 2010-01-06 11:39:13

+3

它更preferrable做:'私人最终名单 myList中=新的ArrayList ();' – Bombe 2010-01-06 12:05:20

回答

13

第一个变体将始终实例化数组列表,第二个变量将仅在调用默认构造函数时实例化。对于第二种解决方案的意义,您必须为您添加的任何其他构造函数调用默认构造函数,例如

public class Whatever { 
    private final List<String> myList; 

    public Whatever() { 
    myList = new ArrayList<String>(); 
    } 

    public Whatever(String name) { 
    this(); 
    // Other stuff done 
    } 

    public Whatever(List<String> myList) { 
    this.myList = myList; 
    } 
} 

(第二)“懒惰”初始化方法可能会更好,如果你不经常使用的清单(例如,如果你在另一个构造一样,直接在我的例子设置列表),并希望避免造成不必要的对象。 (编辑:我改变了ArrayList到一个接口,并将其设置为最终的。这不是问题的一部分,但它是 - 如评论中所述 - 使用List集合的最佳方式)。

3

的JVM首先执行码,如本(构造外):

public class Whatever { 
    private ArrayList<String> myList = new ArrayList<String>(); 
    // more code goes here 
} 

才把代码,如下所示(在构造器):

public class Whatever { 
    private ArrayList<String> myList = null; 

    public Whatever() { 
    myList = new ArrayList<String>(); 
    } 
} 

所以,除非的顺序执行对你来说很重要,我想@达夫的答案是正确的。

3

在这个特定的例子中,除了第一种形式更短以外没有区别。但是,如果属性初始化表达式(可能)抛出异常,则第二种形式允许您捕获异常,或将它们声明为在构造函数签名中抛出。

当然,如果您有多个构造函数,第二种形式允许您在每个构造函数中以不同方式初始化属性......或者使用构造函数链来初始化相同的属性......或者混合两种初始化类型。

相关问题