This site is currently read-only as we are migrating to Oracle Forums for an improved community experience. You will not be able to initiate activity until January 30th, when you will be able to use this site as normal.

    Forum Stats

  • 3,890,299 Users
  • 2,269,776 Discussions
  • 7,916,824 Comments

Discussions

Generics and supertypes

843793
843793 Member Posts: 41,732 Green Ribbon
edited Apr 30, 2010 8:11AM in Generics
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 ...

Comments

  • EJP
    EJP Member Posts: 32,943 Gold Crown
    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>>();
  • 843793
    843793 Member Posts: 41,732 Green Ribbon
    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.
  • 843793
    843793 Member Posts: 41,732 Green Ribbon
    edited Apr 9, 2010 3:40PM
    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.
  • 843793
    843793 Member Posts: 41,732 Green Ribbon
    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.
This discussion has been closed.