matthias
matthias

Reputation: 2062

Java Generics in arguments

I have the following interface:

public interface IRadioButtonGroup<T> {
 List<IRadioButton<T>> getButtons();
}

Now I create a method

protected Object getDefaultRadioButtonValue(IRadioButtonGroup<?> field) {
List<IRadioButton<?>> buttons = field.getButtons();

Now java is complaining:

Type mismatch: cannot convert from List<IRadioButton<capture#1-of ?>> to List<IRadioButton<?>>

Any suggestions?

Upvotes: 1

Views: 78

Answers (4)

Rohit Jain
Rohit Jain

Reputation: 213223

The unbounded wildcard parameter type of your method means that, it will accept an IRadioButtonGroup of an unknown type. The compiler doesn't know what type will come, but at compilation time, the compiler does generate and assign each wildcards with a placeholder, because although it doesn't know which type is coming, it is sure that there has to be a single type that will replace ?. And that placeholder is capture#1-of ? you see in the error message.

Basically, you are trying to assign a List<IRadioButton<Cap#1-of-?>> to a List<IRadioButton<?>>, and that is not valid, in a similar way how List<List<String>> cannot be assigned to List<List<?>>.

One well known way to solve these issues is to use capture helpers. Basically you create a generic method, and delegate the call to that method. That generic method will infer the type parameter and then you would be able to do type safe operation. See this Brian Goetz's article for more details.

So to solve the issue, provide another method as in below code:

protected Object getDefaultRadioButtonValue(IRadioButtonGroup<?> field) {       
    return getDefaultRadioButtonValueHelper(field);
}

private <T> Object getDefaultRadioButtonValueHelper(IRadioButtonGroup<T> field) {
    List<IRadioButton<T>> buttons = field.getButtons();
    // Write the logic of original method here
}

Upvotes: 2

Harmlezz
Harmlezz

Reputation: 8068

Change:

protected Object getDefaultRadioButtonValue(IRadioButtonGroup<?> field) { List<IRadioButton<?>> buttons = field.getButtons();

to:

protected Object getDefaultRadioButtonValue(IRadioButtonGroup<IRadioButton<?>> field) {

List> buttons = field.getButtons();

Upvotes: 0

fluminis
fluminis

Reputation: 4049

You could do:

protected <T> Object getDefaultRadioButtonValue(IRadioButtonGroup<T> field) {
    List<IRadioButton<T>> buttons = field.getButtons();
    return buttons;
}

or

protected Object getDefaultRadioButtonValue(IRadioButtonGroup<?> field) {
    return field.getButtons();
}

Upvotes: 0

Joakim M
Joakim M

Reputation: 1803

List<IRadioButton<?>> buttons = new List<IRadioButton<?>>();

foreach(IRadioButton button in field.getButtons())
{
 buttons.Add(button);
}

Upvotes: 0

Related Questions