当前位置:  开发笔记 > 编程语言 > 正文

为了添加实例初始化块而创建的匿名类的意外后果

如何解决《为了添加实例初始化块而创建的匿名类的意外后果》经验,为你挑选了2个好方法。

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

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

程序员匿名扩展ArrayList只是为了在实例初始化块中推迟.

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

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

那么第一种方式做到这一点的意外后果是什么?



1> cletus..:

这种代码(在一般情况下)的危险在于你可能会破坏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,所以你很好.

但是要注意这一点.

我建议的是略有不同:

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

当然,它更加冗长,但你不太可能以这种方式遇到麻烦,因为结果类是"纯粹的" ArrayList.



2> Brian Agnew..:

我认为这里最大的问题是你正在创建周围类的内部类.您创建的列表将有一个隐含的这一参考外部类.

这通常不是问题.但是,如果你序列化这个对象(我正在考虑使用XStream,因为我自己遇到过这个),那么序列化的表单将包含序列化的外部类.这根本不是你通常所期望的,并且可能导致奇怪的行为!

我经常使用上面的初始化模式.只要您了解内部类机制,那么它就不是问题.BTW.我不认为平等问题超出了一般推导的平等实现的问题.

推荐阅读
手机用户2402851335
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有