سؤال

My code is supposed to call the handleInput(String) method from a non-specific class that implements the interface InputType; this is to force all handler classes that could be here to have the method handleInput(String), along with some other methods.

Am I doing this wrong? Eclipse says that

The method handleInput(String) is undefined for the type
Class<capture#5-of ? extends InputType>

Code:

public void registerNewInput(String name, Class<? extends InputType> typeHandler)
{
    inputHandlers.put(name, typeHandler);
}

public void handleInput(String handlerName, String input)
{
    Class<? extends InputType> handler = (Class<? extends InputType>) inputHandlers.get(handlerName);
    handler.handleInput(input);
}
هل كانت مفيدة؟

المحلول

You don't need generics to accomplish this. Simply use the interface name as your type:

public void registerNewInput(String name, InputType typeHandler)
{
    inputHandlers.put(name, typeHandler);
}

public void handleInput(String handlerName, String input)
{
    InputType handler = (InputType) inputHandlers.get(handlerName);
    handler.handleInput(input);
}

The reason you don't need generics here is because Java types can always be assigned to a variable of a more general type. I.e. - if Circle extends Shape, then a Circle can be assigned to a reference of type Shape:

Shape s = new Circle();  // works just fine

So in this example, it allows you to declare your parameter as type InputType and pass anything that implements InputType when calling the method.

Additionally, you can save yourself a cast by parameterizing your map

private Map<String, InputType> inputHandlers;

public void registerNewInput(String name, InputType typeHandler)
{
    inputHandlers.put(name, typeHandler);
}

public void handleInput(String handlerName, String input)
{
    InputType handler = inputHandlers.get(handlerName); // no cast needed here
    handler.handleInput(input);
}

نصائح أخرى

If handler is supposed to be of some class that implements InputType, then just declare it like this:

InputType handler = inputHandlers.get(handlerName);

Whenever you declare a variable like this:

SomeClass x;

it means that, at runtime, x can be a SomeClass or any subclass of SomeClass. For an interface, x can be of any class that implements the interface. I'm guessing that that's what you were trying to say with Class<? extends InputType>.

EDIT: If I've guessed correctly what you're trying to do, then changing Class<? extends InputType> to simply InputType should be done everywhere, including the typeHandler parameter of registerNewInput, and in your Map type if you're using one. A Class object is a special type of object that can be used to give you information about a class; don't use the type for declaring objects that should just be in some unknown class. (On the other hand, if you are really sure you do want a Class object, please clarify what you're trying to accomplish.)

You're working with the class and not an instance of your InputType. You have to create an instance of that class and then call handleInput on it:

public void handleInput(String handlerName, String input)
{
    Class<? extends InputType> clazz = inputHandlers.get(handlerName);
    InputType handler = clazz.newInstance();
    handler.handleInput(input);
}

But this seems rather convoluted. Is there a reason that you're storing the class of the handler instead of an instance of the handler itself? You could easily do this instead:

public void registerNewInput(String name, InputType inputType) {
    inputHandlers.put(name, inputType); //This assumes your map is of type Map<String, InputType>
}

public void handleInput(String handlerName, String input) {
    InputType inputType = InputType inputHandlers.get(handlerName);
    inputType.handleInput(input);
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top