实例化列表VS代理列表VS检查空引用?

时间:2012-04-03 15:39:25

标签: java

我在java中编码,但我认为这个问题与一种语言无关。

我的问题发生在我们与同事谈论对象列表时,这是一个类的领域。我说我总是初始化List with和空列表。所以我可以直接使用这个列表的getter而不检查它是否为null:

myObject.getList().add(o)

他说我喜欢不为列表创建一个getter,因为他不想检查列表是否为null,因此他创建了一个“addItemToMyList”方法来将项添加到列表中。通过这种方式,他可以在此方法中控制列表不为空(如果是这种情况,则创建它),并且毫无疑问以这种方式使用列表。

我认为为我们使用的每个列表编写很多方法可能需要做很多工作(获取大小,添加,删除......)。

摘要:


案例1:始终初始化字段

上课:

class MyObject {
  private List<X> list = new ArrayList<X>();

  public List<X> getList() { return list; }
}

用法:

MyObject myObj = new MyObject();
myObj.getList().add(anObject);

VS案例2:代理列表

上课:

class MyObject {
  private List<X> list;

  public void addItemToList(X item) { 
    if (list == null) list = new ArrayList<X>();
    list.add(item);
  }

  ... // methods to get the size, remove item...

}

用法:

MyObject obj = new MyObject();
obj.addItemToList(anObject);

VS案例3:检查空引用

上课:

class MyObject {
  private List<X> list;

  public List<X> getList() { return list; }
  public List<X> setList(List<X> list) { this.list = list; }
}

用法:

MyObject myObj = new MyObject();
if (myObj.getList() == null) myObj.setList(new ArrayList<X>());
myObj.getList().add(anObject);

对于列表和一般复杂字段,有什么好方法?

2 个答案:

答案 0 :(得分:2)

我认为这是主观的,但是:

  • 我会因为你提到的原因而避免使用案例3.
  • 我可能会混合使用1&amp; 2,没有懒惰的初始化,这会使你的生活变得更复杂,并且在性能方面增加很少(如果有的话),并使列表最终。

-

class MyObject {
  private final List<X> list = new ArrayList<>();

  public void addItemToList(X item) { 
    list.add(item);
  }

  ... // methods to get the size, remove item...

}

现在让我们假设在稍后阶段你想要使该类线程安全并添加一个需要2个操作原子化的方法,很容易添加相关代码而不改变其他任何东西:

class MyObject {
  private final List<X> list = new ArrayList<>();
  private final Object listLock = new Object();

  public void addItemToList(X item) {
    synchronized(listLock) {
        list.add(item);
    }
  }

  public void addItemToListIfEmpty(X item) { //let's say you need that method
    synchronized(listLock) { //you can make the operation atomic
        if (list.isEmpty()) {
            list.add(item);
        }
    }
  }
  ... // methods to get the size, remove item...

}

而在解决方案1中,您需要更改使用该列表的所有代码。

如果主叫代码确实需要整个列表,您可以随时返回副本,以便他们可以使用它。

答案 1 :(得分:1)

一般来说,我更喜欢第一种方法 - 只是因为list是你的代码的一部分(在本例中是你的类),你可以确保列表总是非空的,从而节省了所有的支票。关于第二种和第三种方法 - 所有访问者都需要进行此类检查,并且会产生不需要的代码重复。

作为奖励,使用第一种方法将允许您将列表指定为final实例,使您的类“更”线程安全。