4 Replies Latest reply: Apr 30, 2010 7:11 AM by 843793 RSS

    Generics and supertypes

    843793
      Hi,

      I have an issue with Generics and types, I hope I may find some help here.

      I have the following map :
      protected static HashMap<String, Action<EndpointClient>> dictionary = 
          new HashMap<String, Action<EndpointClient>>();
      In this map I want to put :
      protected static final Action<EndpointClient> ACTION_SEND_PRIVATE = new ActionSendPrivateMessage();
      protected static final Action<EndpointClientAdmin> ACTION_SEND_TO_ALL = new ActionSendMessageToAll();
      
      dictionary.put(Constants.MSG_SEND_PRIVATE, ACTION_SEND_PRIVATE);
      dictionary.put(Constants.MSG_SEND_TO_ALL, ACTION_SEND_TO_ALL);
      I have a problem in adding the ACTION_SEND_TO_ALL variable in the map, it says :
      The method put(String, Action<EndpointClient>) in the type+
      HashMap<String,Action<EndpointClient>> is not applicable for the arguments (String,  Action<EndpointClientAdmin>)+

      However EndpointClientAdmin extends EndpointClient ...

      In java it's possible to to do something like:
      List myList = new ArrayList();
      and thus reduce the visibility of the class ArrayList.

      Why isn't it possible with Generics like this case above ?

      Thank you very much ...
        • 1. Re: Generics and supertypes
          EJP
          protected static HashMap<String, Action<EndpointClient>> dictionary = 
          new HashMap<String, Action<EndpointClient>>();
          protected static Map<String, Action<? extends EndpointClient>> dictionary = 
              new HashMap<String, Action<EndpointClient>>();
          • 2. Re: Generics and supertypes
            843793
            Thanks again ejp for your help !

            It seems that now in my code I have to put anywhere :
            Action<? extends Client>

            What confuses me is that i can't do something like:
            public Action<? extends Client> getAction(String command) {
            ...
            }
            
            Action<EndpointClient> action = directory.getAction(command);
            (of course EndpointClient is extending Client, both are itnerfaces)

            Or is it a normal thing to have anywhere something like Action<? extends Client>

            Thank you.
            • 3. Re: Generics and supertypes
              843793
              So I replaced by <? extends Client> (EndpointClient and EndpointClientAdmin are both extending Client)
              But I have a new error generated :
              public MessageProcessor(String data, String command, EndpointClient client) {
              // some code
              Action<? extends Client> action = dictionary.getAction(command);
              action.execute(listFields, client);  // Compliation error
              The method execute(LinkedList<String>, capture#3-of ? extends Client) in the type+
              +      Action<capture#3-of ? extends Client> is not applicable for the arguments (LinkedList<String>,+
              +      EndpointClient)+

              The dictionary is a map containing Action<EndpointClient> and Action<EndpointClientAdmin> elements. I used here Generics because I have in the class Action a function containing a reference to EndpointClient OR EndpointClientAdmin (so the Generics would allow me to avoid some casting)
              protected static HashMap<String, Action<? extends Client>> dictionary = new HashMap<String, Action<? extends Client>>();
              (EndpointClient and EndpointClientAdmin both are interfaces extending Client interface)

              Here is the code of the abstract class Action and two sample subclasses :
              // Action abstract class
              public abstract class Action<C extends Client> {
                  public abstract void execute(LinkedList<String> fields, C client);
              // ActionValidateConnection class
              public class ActionValidateConnection extends Action<EndpointClient> {
                  public void execute(LinkedList<String> fields, EndpointClient client) {
              // ActionEcho class
              public class ActionEcho extends Action<EndpointClientAdmin> {
                  public void execute(LinkedList<String> fields, EndpointClientAdmin client) {
              If I replace
              Action<? extends Client> action = dictionary.getAction(command);
              by
              Action<EndpointClient> action = dictionary.getAction(command);
              It works, of course I'll have an error because getAction returns <? extends Client>, even though EndpointClient extends Client

              Thanks for the help.
              • 4. Re: Generics and supertypes
                843793
                It seems you have a Problem in the design...

                In the first code sniplet, suppose the passed command matches a Action<EndpointClientAdmin>, what is it supposed to do with a client of type EndpointClient? It's execute(LinkedList<String> fields, EndpointClientAdmin client) method cant handle this type.