【问题标题】:How can I compare objects using instanceof but Interface types (not passing exact class name.)如何使用 instanceof 但接口类型比较对象(不传递确切的类名。)
【发布时间】:2013-09-24 04:33:42
【问题描述】:
public interface Component{}

public class AppManager {


  public void doWork(){
    SomeComponent comp = new SomeComponent ();
    AddComponentToList(comp);

  }

  public void AddComponentToList(Component compo){
     componentList.add(compo);
  }

  /* Give me the component I want. */
  public Component getComponent(Component comp){
    for (Component component : getComponentList()) {

        if (component instanceof comp) {
          return component;  
        }

    }


  }

   private ArrayList<Component> componentList  = new ArrayList<Component>();

}

public class SomeComponent implements component {

  public void MyMethod() {

     appManager.getComponent(SomeComponent );
  }


  public void setAppMnger(AppManager appm){
     this.appManager = appm;
  }

  private AppManager appManager ;
}

在上面的代码中,AppManger 有一个组件列表。组件相互通信。因此,如果一个组件想知道另一个组件实例,它会调用 AppMnger getComponent(comp) 方法。但是当我使用 instanceof 运算符时出现错误。我不希望每个组件都比较列表,但我想将该任务委托给 AppMnger,因为他是知道它创建的组件的人。 艾米想?

【问题讨论】:

  • 旁注 - 我强烈建议您避免删除元音,因为这样简洁。 “AppManager”甚至“ApplicationManager”比“AppManger”更好
  • 关于componentcomp 之间的关系,您可能会想问多个问题,例如“它们有相同的类吗?”或“它们都有接口吗?”实现?”,或“它们都实现了这组接口中的任何一个吗?”。所有这些问题都可以通过两个参考来回答。你能说得更具体点吗?
  • 我想检查并从 componentList 中找到我想要的确切的具体类实例。我正在传递 appMnger.getComponent(SomeComponent);我想从列表中找到 SomeComponent 实例。

标签: java interface compare delegation instanceof


【解决方案1】:

我认为您应该重新设计getComponent 以采用Class&lt;? extends Component&gt; 而不是Component。然后你可以使用isInstance:

public Component getComponent(Class<? extends Component> componentClass) {
    for (Component component : getComponentList()) {
        if (componentClass.isInstance(component)) {
           return component;  
        }
    }
    return null; // Or throw an exception, potentially.
}

SomeComponent 会使用:

appManager.getComponent(SomeComponent.class);

如果你真的想要使用一个实例,你可以像这样重载方法:

public Component getComponent(Component existingComponent) {
    return getComponent(existingComponent.getClass());
}

编辑:如果你真的只想检查 exact 类,你不想要instanceof-like 行为 - 你只想要:

public Component getComponent(Class<? extends Component> componentClass) {
    for (Component component : getComponentList()) {
        if (componentClass == component.getClass()) {
           return component;  
        }
    }
    return null; // Or throw an exception, potentially.
}

我仍然建议使用此方法签名 - 必须已经拥有一个组件实例才能找到输入你想要的。

【讨论】:

  • 嗨,乔恩,我尝试使用第一个选项,但它给了我关于找不到返回语句的错误。
  • @user2771655:已修复 - 这是我没有发现的原始伪代码中的问题。
  • 好的。这给我带来了另一个问题。为什么在 if 块中找不到 return 语句?
  • @user2771655:确实如此——但如果一个方法有一个非 void 返回类型,那么你不能在不返回一些东西的情况下到达方法的末尾。考虑根本没有组件的情况,或者更一般地说,如果没有与指定类型匹配的组件 - 那你想发生什么?
  • 我在将 SomeComponent.class 传递给 getComponent() 时收到此错误“ApplicationManager 类型中的方法 getComponent(Class extends Component>) 不适用于参数
【解决方案2】:

如果您希望类完全匹配 (List != ArrayList),请使用:

if (comp.getClass().equals(component.getClass())) ...

如果你想让它像 instanceof (List => ArrayList) 一样工作,那么你可以试试这个:

if (comp.getClass().isInstance(component)) ...

【讨论】:

  • 基于澄清评论“我想从 componentList 检查并找到我想要的确切的具体类实例。我正在传递 appMnger.getComponent(SomeComponent); 我想从中找到 SomeComponent 实例名单。”我认为第一个选择是正确的答案。
  • @PatriciaShanahan:是的,我已经编辑了我的答案以表明这一点。问题中对instanceof 的引用具有误导性:(
【解决方案3】:

我猜 Black,max 和 Jon 之前的回答对于您的比较部分来说已经足够了,因为“我不希望每个组件都想要比较列表,但我想将该任务委托给 AppManger,因为他是“谁知道它创建的组件。艾米想?”您可以尝试使用访问者设计模式。

【讨论】:

    猜你喜欢
    • 2021-04-01
    • 2020-07-17
    • 2019-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-25
    • 2020-09-12
    相关资源
    最近更新 更多