这是一个关于Java代码的问题,例如:
List<String> list = new ArrayList<String>() {{add("hello"); add("goodbye");}}
程序员为了在实例初始化块中推迟而匿名扩展了ArrayList。
问题是:如果程序员的唯一目的只是为了达到以下目的:
List<String> list = new ArrayList<String>();
list.add("hello");
list.add("goodbye");
然后第一种方式做出的意外后果是什么?
答案 0 :(得分: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()
方法只检查另一个对象是instanceof
接口List
,所以你很好。< / p>
但是要注意这一点。
我建议的做法略有不同:
List<String> list = new ArrayList<String>(
Arrays.asList("hello", "goodbye")
);
当然这更加冗长,但你不太可能以这种方式遇到麻烦,因为结果类是“纯粹的”ArrayList
。
答案 1 :(得分:5)
我认为这里的一大问题是你正在创建周围类的内部类。您创建的列表将具有对外部类的隐式 this 引用。
这通常不是问题。但是,如果你序列化这个对象(我特别考虑使用XStream,因为我自己遇到过这个),那么序列化的表单将包含序列化的外部类。这根本不是你通常所期望的,可能导致特殊的行为!
我经常使用上面的初始化模式。只要您了解内部类机制,那么它就不是问题。 BTW。我不认为平等问题超出了一般推导的平等实现的问题。
答案 2 :(得分:2)
对代码性能和/或内存的影响可以忽略不计(甚至可以测量)。
真正的打击是,你让人们停下来,即使是一个节拍,也要想“这个人在做什么?”
如果我在阅读代码时必须这样做1000次,那就是性能问题。
代码应易于阅读 - 只要满足所有性能,完整性和标准要求。
您很可能会成为维护代码的人。对未来的自我保持友好,并使代码尽可能易于阅读。如果你打算做一些像这样的花哨的schmancy东西,有充分的理由并在代码中记录它。如果唯一的原因是作为程序员炫耀你的排骨,那么你在程序员的实际工作中就失败了:让困难变得容易。
答案 3 :(得分:0)
第一种方法对性能也不利。包含大量匿名类的内存混乱并不好。它在启动时也会变慢。