4

这是一个关于 Java 代码的问题,例如:

List<String> list = new ArrayList<String>() {{add("hello"); add("goodbye");}}

程序员匿名扩展 ArrayList 只是为了插入实例初始化块。

问题是:如果程序员的唯一目的仅仅是为了达到以下目的:

List<String> list = new ArrayList<String>();
list.add("hello");
list.add("goodbye");    

那么第一种方式的意外后果是什么?

4

4 回答 4

15

执行此类代码(在一般情况下)的危险在于您可能会破坏equals()方法。那是因为有两个通用模板equals()

public boolean equals(Object ob) {
  if (!(ob instanceof MyClass)) return false;
  ...
}

public boolean equals(Object ob) {
  if (ob.getClass() != getClass()) return false;
  ...
}

第一个仍然适用于您正在谈论的匿名子类,但第二个不会。事实是,第二个被认为是最佳实践,因为 instanceof 不一定是可交换的(意思a.equals(b)可能不等于b.equals(a))。

但是,在这种情况下,特别是ArrayList使用AbstractList.equals()仅检查另一个对象是否为instanceofinterface的方法List,所以你很好。

然而,这是需要注意的。

我的建议是稍微不同:

List<String> list = new ArrayList<String>(
    Arrays.asList("hello", "goodbye")
);

当然它更罗嗦,但你不太可能以这种方式遇到麻烦,因为结果类是“纯”的ArrayList

于 2009-03-22T21:40:43.843 回答
5

我认为这里的大问题是您正在创建周围类的内部类。您创建的列表将隐含this对外部类的引用。

这通常不是问题。但是,如果你序列化这个对象(我特别想使用XStream,因为我自己也遇到过),那么序列化的表单将包含序列化的外部类。这根本不是您通常所期望的,并且可能导致异常行为!

我经常使用上述初始化模式。只要您了解内部类机制,就不是问题。顺便提一句。我不认为平等问题是超越一般派生平等实现的问题。

于 2009-03-23T09:03:13.890 回答
2

对代码性能和/或内存的影响可以忽略不计(即使是可测量的)。

这里真正的打击是你让人们停下来,即使是一拍,思考“这家伙在做什么?”

如果我在阅读您的代码时必须这样做 1,000 次,则存在性能问题。

代码应该易于阅读——只要满足所有性能、完整性和标准要求。

您很可能会成为维护代码的人。善待未来的自己,让代码尽可能容易阅读。如果你要做一些像这样花哨的东西,有充分的理由并在代码中记录它。如果唯一的原因是为了炫耀你作为程序员的能力,那么你在程序员的真正工作上就失败了:让困难变得简单。

于 2009-03-23T10:32:35.720 回答
0

第一种方法对性能也不利。大量匿名类使内存混乱是不好的。启动时也会变慢。

于 2009-03-22T22:23:41.697 回答