This question may have some similar ones, but I hope you can look at the code structure here and provide some insight. I believe this either demonstrates a very subtle user error, or a very subtle unaddressed issue in the Java type system. This is a case in which Java struggles to infer the type of an argument passed into a method with the error message:
java: method process in class Usage cannot be applied to given types;
required: OuterWrapper<C,InnerWrapper<C>>
found: RealOuterWrapper
reason: cannot infer type-variable(s) C
(argument mismatch; RealOuterWrapper cannot be converted to OuterWrapper<C,InnerWrapper<C>>)
One interesting detail is that very similar code (listed at the bottom) does compile and run.
Usage.java:
public static <C extends Model> void process (OuterWrapper<C, InnerWrapper<C>> wrapper) {
;
}
public static void main(String[] args) {
process(new RealOuterWrapper());
}
OuterWrapper.java:
public interface OuterWrapper <T extends Model, D extends InnerWrapper<T> >{}
RealOuterWrapper.java:
public class RealOuterWrapper implements OuterWrapper<RealModel, RealInnerWrapper>{}
InnerWrapper.java:
public interface InnerWrapper <T extends Model>{}
RealInnerWrapper.java:
public interface RealInnerWrapper extends InnerWrapper<RealModel>{}
Model.java:
public interface Model {}
RealModel.java:
public class RealModel implements Model {}
This code fails to compile. However, this code compiles successfully:
Usage.java:
public class Usage {
public static <C extends Model> void process (Wrapper<C,C> wrapper) {
;
}
public static void main(String[] args) {
process(new RealWrapper());
}
}
Wrapper.java:
public interface Wrapper <A extends Model,B extends Model>{}
RealWrapper.java:
public class RealWrapper implements Wrapper<RealModel,RealModel>{}
Model.java:
public interface Model {}
RealModel.java:
public class RealModel implements Model {}
Finally, if this wall of text is too hard to reason about, here is my GitHub repo containing these files!
Edit: Rewriting RealInnerWrapper
as a class that implements InnerWrapper
, I added
Usage.java:
public static void main(String[] args) {
process(new RealOuterWrapper());
process2(new RealInnerWrapper());
}
public static void process2 (InnerWrapper<RealModel> wrapper) {
;
}
However, the latter method process2
gives no such error, which implies a RealInnerWrapper()
is an InnerWrapper<RealModel>
.