Community
Participate
Working Groups
This set of files compiled fine in M6 and M7 and the jdk 1.5.0 from Sun, but does not compile in RC1. Controller.java package foo; public interface Controller<T extends Model,U extends View<T,?>> { public U getView() ; public T getTarget() ; } Model.java package foo; public interface Model { } MouseEventReceiver.java package foo; import java.awt.Component ; public interface MouseEventReceiver { public interface Model extends foo.Model { } public interface View<T extends Model,U extends Component> extends foo.View<T,U> { } public interface Ctrl<T extends Model,U extends View<T,?>> extends Controller<T,U> { } } View.java package foo; public interface View<T extends Model, U> { public T getModel(); public U getContent(); } test.java package foo; import java.awt.Component; public class test { public static void main(String [] args) { MouseEventReceiver.Ctrl<?,?> ctrl = null ; foobar(ctrl.getView().getContent()) ; } public static void foobar(Component c) { } } I get: The method foobar(Component) in the type test is not applicable for the arguments (?) It is not correctly determining that ? is bound to Component.
Reduced testcase: package foo; public class Test { public static void main(String[] args) { Controller<?> ctrl = null; foobar(ctrl.getView().getContent()); } static void foobar(Test t) { } } interface Controller<T extends View<?>> { public T getView() ; } interface View<U extends Test> { public U getContent(); }
Reason for change is tightened capture conversion. When 'ctrl' gets capture conversion applied, what is the fresh type variable (say S) upper bound ? Is it: (1) strictly View<?> (2) or rather View<capture-of ?> ? (which I am guessing) If (1) is true, then the program should be rejected I think, as the type of ctrl.getView() would yield 'capture-of ?', then next call for #getContent() will issue '?' (from View<?>). Then this type hasn't been captured, and doesn't know enough to be a proper 'Test' as mandated by #foobar(...) invocation. If (2) is true, then it seems to indicate that capture conversion would have to recurse when computing the bounds of the fresh type variables. However, then I am wondering about infinite regressions when capturing some type Y<?> where class Y<T extends Y<?>> {}; if capturing is allocating a fresh variable each time it encounters Y<?>; could be closed by reusing same capture; but then it would change semantics and handle class Y<T extends Y<?>> {}; as if it had been defined: class Y<T extends Y<T>> {};
I can make this scenario work, by adding back type variable bounds in wildcard direct supertypes. But as demonstrated by following program, it reveals non substituted variables: public class X<E> { public static void main(String[] args) { Controller<?> ctrl = null; foobar(ctrl.getView().getContent()); } static void foobar(X<String> x) { } } interface Controller<T extends View<?>> { public T getView() ; } interface View<U extends X<U>> { public U getContent(); } javac: X.java:6: foobar(X<java.lang.String>) in X<E> cannot be applied to (X<U>) foobar(ctrl.getView().getContent()); ^ 1 error (U shouldn't appear outside its context !?)
Tuned wildcard supertypes to meet old behavior and javac. May reconsider this behavior in the light of spec revision.
Added GenericTypeTest#test726-728. Fixed
Verified in N20050609-0010 + JDT/Core HEAD.
Verified for 3.1 RC2 using build I20050610-0010