Suppose I have the following classes:
interface MyS<T extends MyT<S, T>, S extends MyS<T, S>> { } interface MyT<S extends MyS<T, S>, T extends MyT<S, T>> { } public class MySImpl implements MyS<MyTImpl, MySImpl> { } public class MyTImpl implements MyT<MySImpl, MyTImpl> { }
I can create the following test file that compiles and runs without warning:
public class STTest { @Test public void test() throws Exception { createInstance(MyTImpl.class); } public static<T extends MyT<S, T>, S extends MyS<T, S>> void createInstance( final Class<? extends MyT<S, T>> beanClass) throws Exception { final MyT<S, T> bean = beanClass.newInstance(); } }
Good Excellent. But I expected this to have the same effect:
public class STTest { @Test public void test() throws Exception { createInstance(MyTImpl.class); } public static<T extends MyT<S, T>, S extends MyS<T, S>> void createInstance( final Class<T> beanClass) throws Exception { final T bean = beanClass.newInstance(); } }
However, this is a compilation error:
invalid deduced types for S; supposed type does not match declared bounds (s): mySImpl bound (s): MyS
Why is this?
UPDATE:
I noticed that the behavior is compiler dependent. I used the OpenJDK 1.6 compiler (javac 1.6.0_27) to compile the code. And it breaks. But:
- OpenJDK 1.7 compiler (javac 1.7.0_21) and
- Oracle 1.6 compiler (javac 1.6.0_37)
both work fine in the second example.
However: Is this a bug in the OpenJDK 1.6 compiler or is it an ambiguity in the Java language specification?