Let's consider following code:
interface Iface<A1, A2 extends A1> {
String m(A1 t);
}
public class Test {
public static void run() {
Iface<? super Number, ? extends Integer> i = (Number a) -> "";
}
}
It compiles successfully by javac from JDKb127 but according to reasoning presented below compilation should fail.
1. 18.5.3 is applied to find a ground type of lambda expression according to jls-15.27.3-200-A.
2. jls-18.5.3-210 results in creating just one equality constraint A1=Number which reduces to corresponding bound.
3. A'1=Number according to jls-18.5.3-220-A.
4. A'2=? extends Integer according to jls-18.5.3-220-B.
5. Thus jls-18.5.3-220 results in F<A'1, A'2>=F<Number, ? extends Integer>.
6. F<A'1, A'2>=F<Number, ? extends Integer> is well-formed and contains a wildcard so according to jls-18.5.3-230 non-wildcard parameterization is to be found.
7. According to jls-9.9-200-C.1-B there is no function type because A'2=? extends Integer is a wildcard and its type parameter bound mentions another type parameter - A1.
So compiler error should occur but it doesn't.
JLS 8 assertions:
If T is a wildcard-parameterized functional interface type and the lambda expression is explicitly typed, then the ground target type is inferred as described in §18.5.3. (jls-15.27.3-200-A)
If n ≠ k, no valid parameterization exists. Otherwise, a set of constraint formulas is formed with, for all i (1 ≤ i ≤ n), ‹Pi = Qi›. This constraint formula set is reduced to form the bound set B.(jls-18.5.3-210)
If B contains the bound false, no valid parameterization exists. Otherwise, a new parameterization of the functional interface type, F<A'1, ..., A'm>, is constructed as follows, for 1 ≤ i ≤ m: (jls-18.5.3-220)
If B contains an instantiation for ai, T, then A'i = T. (jls-18.5.3-220-A)
Otherwise, A'i = Ai. (jls-18.5.3-220-B)
If F<A'1, ..., A'm> is not a well-formed type (that is, the type arguments are not within their bounds), or if F<A'1, ..., A'm> is not a subtype of F<A1, ..., Am>, no valid parameterization exists. Otherwise, the inferred parameterization is either F<A'1, ..., A'm>, if all the type arguments are types, or the non-wildcard parameterization (§9.8) of F<A'1, ..., A'm>, if one or more type arguments are still wildcards. (jls-18.5.3-230)
If Ai is a wildcard, and the corresponding type parameter's bound, Bi, mentions one of P1...Pn, then Ti is undefined and there is no function type. (jls-9.9-200-C.1-B)
interface Iface<A1, A2 extends A1> {
String m(A1 t);
}
public class Test {
public static void run() {
Iface<? super Number, ? extends Integer> i = (Number a) -> "";
}
}
It compiles successfully by javac from JDKb127 but according to reasoning presented below compilation should fail.
1. 18.5.3 is applied to find a ground type of lambda expression according to jls-15.27.3-200-A.
2. jls-18.5.3-210 results in creating just one equality constraint A1=Number which reduces to corresponding bound.
3. A'1=Number according to jls-18.5.3-220-A.
4. A'2=? extends Integer according to jls-18.5.3-220-B.
5. Thus jls-18.5.3-220 results in F<A'1, A'2>=F<Number, ? extends Integer>.
6. F<A'1, A'2>=F<Number, ? extends Integer> is well-formed and contains a wildcard so according to jls-18.5.3-230 non-wildcard parameterization is to be found.
7. According to jls-9.9-200-C.1-B there is no function type because A'2=? extends Integer is a wildcard and its type parameter bound mentions another type parameter - A1.
So compiler error should occur but it doesn't.
JLS 8 assertions:
If T is a wildcard-parameterized functional interface type and the lambda expression is explicitly typed, then the ground target type is inferred as described in §18.5.3. (jls-15.27.3-200-A)
If n ≠ k, no valid parameterization exists. Otherwise, a set of constraint formulas is formed with, for all i (1 ≤ i ≤ n), ‹Pi = Qi›. This constraint formula set is reduced to form the bound set B.(jls-18.5.3-210)
If B contains the bound false, no valid parameterization exists. Otherwise, a new parameterization of the functional interface type, F<A'1, ..., A'm>, is constructed as follows, for 1 ≤ i ≤ m: (jls-18.5.3-220)
If B contains an instantiation for ai, T, then A'i = T. (jls-18.5.3-220-A)
Otherwise, A'i = Ai. (jls-18.5.3-220-B)
If F<A'1, ..., A'm> is not a well-formed type (that is, the type arguments are not within their bounds), or if F<A'1, ..., A'm> is not a subtype of F<A1, ..., Am>, no valid parameterization exists. Otherwise, the inferred parameterization is either F<A'1, ..., A'm>, if all the type arguments are types, or the non-wildcard parameterization (§9.8) of F<A'1, ..., A'm>, if one or more type arguments are still wildcards. (jls-18.5.3-230)
If Ai is a wildcard, and the corresponding type parameter's bound, Bi, mentions one of P1...Pn, then Ti is undefined and there is no function type. (jls-9.9-200-C.1-B)
- duplicates
-
JDK-8048547 JLS8 9.9: non-wildcard parameterization succeeds unexpectedly
- Open