1
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 ;
}

In Above code AppMnger is having a list of components. Components are communicating each other. So if one component want to know another component instance it call the AppMnger getComponent(comp) method. But I get an error when I use instanceof operator. I don't want each component to want compare the list but I want to delegate that task to AppMnger because he is the one who knows about components it created. Amy thought?

user2771655
  • 1,052
  • 3
  • 20
  • 38
  • 2
    Side comment - I'd strongly advise you to avoid removing vowels for the sake of brevity like this. "AppManager" or even "ApplicationManager" are better names than "AppMnger" – Jon Skeet Sep 19 '13 at 07:38
  • http://stackoverflow.com/questions/10165887/how-to-check-if-some-class-implements-interface – kovrik Sep 19 '13 at 07:40
  • There are multple questions you might be trying to ask about the relationship between `component` and `comp`, such as "Do they have the same class?", or "Is there any interface they both implement?", or "Do they both implement any of this set of interfaces?". All those questions could be answered given two references. Can you be more specific? – Patricia Shanahan Sep 19 '13 at 07:46
  • I want to check and find from componentList the exact concrete class instance that I want. I am passing appMnger.getComponent(SomeComponent); and I want to find the SomeComponent instance from the list. – user2771655 Sep 19 '13 at 07:55

3 Answers3

3

I think you should redesign getComponent to take a Class<? extends Component> rather than a Component. Then you can use 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.
}

And SomeComponent would use:

appManager.getComponent(SomeComponent.class);

If you really wanted to use an instance, you could overload the method like this:

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

EDIT: If you actually only want to check for the exact class, you don't want instanceof-like behaviour - you just want:

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

I would still suggest using this method signature though - it would feel very odd to have to already have an instance of a component in order to find a component of the type you want.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • hi jon, I try to use first option and it gave me error about can't find the return statement. – user2771655 Sep 19 '13 at 08:09
  • @user2771655: Fixed - it was a problem in your original pseudo-code which I hadn't spotted. – Jon Skeet Sep 19 '13 at 08:10
  • OK. That made me another problem. Why it doesn't find the return statement inside the if block? – user2771655 Sep 19 '13 at 08:14
  • @user2771655: It does - but if a method has a non-void return type, then you can't get to the end of the method without returning something. Consider the case where there are no components at all, or more generally if there are no components matching the specified type - what do you want to happen then? – Jon Skeet Sep 19 '13 at 08:15
  • I receive this error when passing the SomeComponent.class to getComponent() "The method getComponent(Class extends Component>) in the type ApplicationManager is not applicable for the arguments – user2771655 Sep 19 '13 at 08:29
  • Jon, Please ignore above comment. I've made a mistake. – user2771655 Sep 19 '13 at 08:34
  • How can I use this with prior java 1.5 version. – user2771655 Oct 15 '13 at 12:56
  • Well you can't use generics at all before Java 1.5, or the enhanced for loop. You could still call `iterator()` though, and just cast the result of `next()` each time. – Jon Skeet Oct 15 '13 at 13:00
2

If you want the class to match exactly (List != ArrayList) then use this:

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

If you want it to work exactly like instanceof (List => ArrayList) then you can try this:

if (comp.getClass().isInstance(component)) ...
bezmax
  • 25,562
  • 10
  • 53
  • 84
  • Based on the clarifying comment "I want to check and find from componentList the exact concrete class instance that I want. I am passing appMnger.getComponent(SomeComponent); and I want to find the SomeComponent instance from the list." I think the first alternative is the correct answer. – Patricia Shanahan Sep 19 '13 at 08:00
  • @PatriciaShanahan: Yup, I've edited my answer to indicate that too. The reference to `instanceof` in the question is misleading :( – Jon Skeet Sep 19 '13 at 08:11
0

I guess previous answers by Black,max and Jon are sufficient enough for your comparison part , for the "I don't want each component to want compare the list but I want to delegate that task to AppMnger because he is the one who knows about components it created. Amy thought?" you can try using the visitor design pattern .

jay
  • 791
  • 8
  • 20