这是一个关于Java代码的问题,例如:
Listlist = new ArrayList () {{add("hello"); add("goodbye");}}
程序员匿名扩展ArrayList只是为了在实例初始化块中推迟.
问题是:如果程序员的唯一目的只是达到以下目的:
Listlist = new ArrayList (); list.add("hello"); list.add("goodbye");
那么第一种方式做到这一点的意外后果是什么?
这种代码(在一般情况下)的危险在于你可能会破坏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
,所以你很好.
但是要注意这一点.
我建议的是略有不同:
Listlist = new ArrayList ( Arrays.asList("hello", "goodbye") );
当然,它更加冗长,但你不太可能以这种方式遇到麻烦,因为结果类是"纯粹的" ArrayList
.
我认为这里最大的问题是你正在创建周围类的内部类.您创建的列表将有一个隐含的这一参考外部类.
这通常不是问题.但是,如果你序列化这个对象(我正在考虑使用XStream,因为我自己遇到过这个),那么序列化的表单将包含序列化的外部类.这根本不是你通常所期望的,并且可能导致奇怪的行为!
我经常使用上面的初始化模式.只要您了解内部类机制,那么它就不是问题.BTW.我不认为平等问题超出了一般推导的平等实现的问题.