初始化时实例化对象?

3

我有一个类,它内部包含了其他对象(List、Set以及我的应用程序中的对象)。

public class SomeClass {
    private List l;
    private SomeObject obj;
    //...
}

在创建SomeClass对象时实例化这些对象是一个好的实践,以避免出现NullPointerException异常。例如:

public class SomeClass{
    private List l = new ArrayList();
    private SomeObject obj = new SomeObject();
    //...
}

通常情况下,这些对象会在某些处理/分析中生成,但是错误可能会发生,导致对象仍然具有 null 值。

6个回答

2

是的,这是一种好的实践。构造函数自然是实例化成员对象的好地方。您也可以在声明它们的地方直接创建它们:

private List l = new ArrayList();

然而,重构或修改代码,使得无论方法调用顺序如何,都不会发生NullPointerException是一个好主意。


所有答案都不错,但这个被选中是因为它建议修改代码以避免NullPointerException,而我完全同意这一点。 - Renato Dinhani

1
如果一个空的List或该类的默认对象在每个后续操作中都是有效状态,那么实例化一个默认对象。但是,如果默认状态将是无效状态,则不要这样做。

1

我更喜欢初始化,因为有时候找到空指针异常的位置很头疼,如果你使用构造函数初始化对象,那么对象内部应该也会被初始化。

希望这能帮到你。


1

通常最好的做法是在创建时实例化成员字段(无论是对象还是原始类型),除非默认值(0、false或null)不是您想要的。延迟实例化的一种情况是懒加载。(例如,当一个对象可能不需要并且创建它很昂贵时使用)。另一种情况是在其他初始化之前需要延迟实例化。

假设您想在对象创建时初始化字段,有两种方法可以做到:使用初始化表达式,就像您展示的那样,或者在构造函数中。除了实例初始化器在构造函数的第一行之前运行之外,没有太大区别。这可能会导致问题,具体取决于您的代码逻辑。

声明成员字段为final也是一个好主意,只要它们在对象创建时被初始化并且预计在对象的生命周期内不会更改。声明字段为final的一个附带好处是编译器将捕获任何未初始化的失败。(编译器需要明确的赋值才能认为final字段已经正确初始化。)


1

你在谈论急切构建与惰性构建。每种方式都有其价值所在的场合。

在许多情况下,惰性创建东西更好,因为它可以节省内存。但是,每次尝试获取数据时,您必须检查是否为空。

在某些情况下,事先创建对象是有意义的,要么是为了避免上述空值检查,要么是为了避免在密集进程期间的对象创建时间开销。


1

像这样生成它们是很正常的,但为了避免NPE而生成它们并不是一种好的编码方式。代码中应该有适当的验证,而不是分配垃圾可回收对象,这些对象将不会被使用。


你也可以指定一些默认的状态 - 比如Collections.emptyList(),或者在一个常量类中:

DEFAULT_STATE = new SomeState();

那么就简单地

class A { 
      State obj = Constants.DEFAULT_STATE;
   }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接