Generic Types incompatible with given method signature?

130 views Asked by At

Given the following method:

public <E> void bindContentBidirectional(final String fieldPath,
        final String itemFieldPath, final Class<?> itemFieldPathType,
        final ObservableList<E> list, final Class<E> listValueType,
        final SelectionModel<E> selectionModel,
        final String selectionModelItemMasterPath)

Am I correct in my understanding that, if I have an ObservableList<PrintablePredicate<SomeClass>> as the type of the:

final ObservableList<E> list

(that is, E = PrintablePredicate<SomeClass> that this can never work because for the next argument:

final Class<E> listValueType) 

I can only write PrintablePredicate.class and not PrintablePredicate.class as generic types are not reified. In other words, the given method signature for bindContentBidirectional is incompatible with all E such that E has generic type arguments.

Putting it all together in a concrete code scenario, say we have:

@FXML private CheckListView<PrintablePredicate<Miner>> profileConditions;      
private MinerMonitorProfile minerMonitorProfile;

private void initialize() {
    BeanPathAdapter<MinerMonitorProfile> minerMonitorProfileBPA = new BeanPathAdapter<>    (this.minerMonitorProfile);
    minerMonitorProfileBPA.bindContentBidirectional("conditions", null, String.class, this.profileConditions.getItems(), PrintablePredicate.class, null, null);
}

the compiler says:

The method bindContentBidirectional(String, String, Class<?>, ObservableList<E>, Class<E>, SelectionModel<E>, String) in the type BeanPathAdapter<MinerMonitorProfile> is not applicable for the arguments (String, null, Class<String>, ObservableList<PrintablePredicate<Miner>>, Class<PrintablePredicate>, null, null)

Is there anyway around this? Thanks!

Note: this.profileConditions.getItems() returns type: ObservableList<PrintablePredicate<Miner>>

Further note that parameterizing the method call as in:

minerMonitorProfileBPA.<PrintablePredicate<Miner>>bindContentBidirectional("conditions", null, String.class, this.profileConditions.getItems(), PrintablePredicate.class, null, null);

does not alleviate the issue.

1

There are 1 answers

5
Rodrigo Quesada On BEST ANSWER

When I have that kind of issues (casting a plain class to a parameterized one?) I use double casting, in order to bypass the compiler complain.

So in your case I guess you could write

(Class<PrintablePredicate<Miner>>)(Class<?>) PrintablePredicate.class

when passing the PrintablePredicate.class parameter to the bindContentBidirectional function.


Edit: I found out that simply casting PrintablePredicate.class to Class (I don't undestand why though, it seems kinda unnecessary on my opinion since *.class are already of type Class) or assigning it to a variable before passing it to the method works for this case (using javac 1.8.0_25). Therefor maybe you should just use this instead of the code above:

(Class)PrintablePredicate.class

So your error might be due to a compiler bug similar to this one from OpenJDK (yeah, which doesn't make sense because it's a bug): https://bugs.openjdk.java.net/browse/JDK-8028682


As a summary then after my findings, this "double casting" trick stuff (or just assigning an object to a variable) can help you "make it easier" for the compiler to "understand" your code when it has a bug such as this one seems (lol, it's kind of funny having to do that I guess, but it just shows you that sometimes you cannot even trust the compiler).