Reputation: 823
Situation: I'm making a configuration library, with a Config interface that represents the data, and a Parser interface like this:
public interface Parser<C extends D, D extends Config> {
C parse(File f);
void parse(File f, D destination);
}
The parser must be able to parse data into a new Config object (C), or an existing one (D). C extends D because it's logical that we can create C manually and parse data into it. And of course D extends Config because we parse configurations.
Let's say we have a class MyConfig that implements Config (but it could as well be a generic "T extends Config"), and we want a Parser that can create and parse it. Let's follow the PECS rule:
Therefore I end up with this:
Parser<? extends MyConfig, ? super MyConfig> parser;
But while IntelliJ doesn't complain about anything, the compilation (javac 1.8.0_131) fails with this error:
type argument ? extends package.MyConfig is not within bounds of type-variable C
Which is weird, because "some subtype of MyConfig" is obviously a subtype of "some supertype of MyConfig", right?
This issue arises only when both wildcards are used. Also, using another generic type instead of the upper bound works:
// All these are fine
Parser<? extends MyConfig, MyConfig>
Parser<MyConfig, ? super MyConfig>
<J extends MyConfig> void test(Parser<J, ? super MyConfig> parser)
What am I missing here? And what can I do with my producer-consumer Parser?
EDIT: I found something even more confusing: using a subinterface of Config instead of a subclass works, ie this compiles perfectly fine:
interface SpecialConfig extends Config {}
Parser<? extends SpecialConfig, ? super SpecialConfig> specialParser;
Upvotes: 3
Views: 118