Java:使用instanceof公开不同的对象方法

时间:2012-02-09 22:52:12

标签: java instanceof

我已经阅读了这篇文章http://www.javapractices.com/topic/TopicAction.do?Id=31,其中说使用instanceof预先检查我的对象是不好的做法。

但是在这种情况下我不知道怎么做:我有一个返回项目列表的API。此项列表返回用户和管理员

如果我投射了一个像(用户)项目的项目,一旦它命中一个Admin,我就会有一个ClassCastException

for(Item item : items){                     
                if (item instanceof User){
                    ((User)item).getName());
                    ((User)item).getEmail());
                }
                else if (item instanceof Admin){
                    ((Admin)item).getName());
                    ((Admin)item).getEmailList().getPrimary());
                }                           
            }

由于它是一个API,我无法修改Item,Item上没有子方法,而且电子邮件检索方法也不同。我还有其他选择吗?

3 个答案:

答案 0 :(得分:5)

使用所有常用方法定义一个接口,让User和Admin类实现该接口,并在这些情况下仅使用该接口来访问对象。

编辑(因为您无法更改API)

备选方案是:

  1. 坚持您当前的解决方案。这似乎是最好的交易。

  2. 定义一个接口,创建两个实现此接口的包装类并包装原始对象。从OOP的角度来看,这更加干净,但我认为在你的情况下这有点过分,但这实际上取决于。

  3. 理论(!):您也可以使用反射,但不要这样做 - 它会使代码更糟糕 - 特别是当只有两个不同的编译时已知项目子类型

答案 1 :(得分:2)

理想情况下,您可以将接口更改为Item,以便它显示方法,以便在您的代码中处理用户或管理员时无关紧要 - 以便Item定义getName()和getEmail()用户和管理员酌情实施这些方法。

但是,由于您不控制您正在使用的API,因此您别无选择,只能按现在的方式编写代码。

因此,引用文章提出的观点很好,但它假设您可以更改您正在使用的类。

答案 2 :(得分:-1)

首先,您的代码没有任何效果。您正在调用getter而没有任何赋值,因此您实际上不使用getter的返回值。

其次,使用不同类型的元素进行集合是一种不好的做法。在你的ccase用户和管理员。

第三,如果你甚至需要这样的收藏,你可以使用其他模式来执行你需要的。例如,访客模式看起来像是一个很好的替代方法。