-
Enhancement
-
Resolution: Fixed
-
P4
-
None
For one functional interface type S to be more specific than unrelated functional interface type T, the function type of *the capture of* S must have the same parameter types as the function type of T. If one of the capture variables appears in the parameter types for S, this condition is impossible to satisfy.
Yet there exist reasonable cases in which one might consider a wildcard-parameterized functional interface type to be "better" than another. E.g.:
void m1(Predicate<? super Integer>) // more specific?
void m1(Function<? super Integer, Boolean>)
Intuitively, the prerequisite for "more specific" is that the less specific method can be safely called from the body of the more specific method. In the case of functional interface types, this may require an adaptation via a lambda, but the lambda needs to be type safe.
m1(Predicate<? super Integer> p) {
Function<? super Integer, Boolean> f =
(Integer i) -> p.test(i); // p.test expects a CAP sup Integer, gets an Integer
return m1(f);
}
We could attempt to provide more flexibility by just dropping the "capture of" part of the rule, but this would lead to cases in which the intuition no longer works:
void m2(Predicate<? extends Integer>) // more specific?
void m2(Function<? super Integer, Boolean>)
m2(Predicate<? extends Integer> p) {
Function<? super Integer, Boolean> f =
(Integer i) -> p.test(i); // p.test expects a CAP ext Integer, gets an Integer
// ERROR!
return m2(f);
}
We could could get there by allowing the captured parameter types from S to be *supertypes of* the parameter types of T, rather than *equal to*. But there are separate reasons that allowing supertypes in full generality was rejected in the design phase of JSR 335 (for example, it allows a method reference to consider a function type more distant from its signature to be considered "more specific").
Perhaps we can enforce both, that the uncaptured function types have the same parameters, but that the captured parameter types are supertypes?
Or maybe we can come up with a way to detect that capture variables are equivalent up to renaming, or something like that?
Yet there exist reasonable cases in which one might consider a wildcard-parameterized functional interface type to be "better" than another. E.g.:
void m1(Predicate<? super Integer>) // more specific?
void m1(Function<? super Integer, Boolean>)
Intuitively, the prerequisite for "more specific" is that the less specific method can be safely called from the body of the more specific method. In the case of functional interface types, this may require an adaptation via a lambda, but the lambda needs to be type safe.
m1(Predicate<? super Integer> p) {
Function<? super Integer, Boolean> f =
(Integer i) -> p.test(i); // p.test expects a CAP sup Integer, gets an Integer
return m1(f);
}
We could attempt to provide more flexibility by just dropping the "capture of" part of the rule, but this would lead to cases in which the intuition no longer works:
void m2(Predicate<? extends Integer>) // more specific?
void m2(Function<? super Integer, Boolean>)
m2(Predicate<? extends Integer> p) {
Function<? super Integer, Boolean> f =
(Integer i) -> p.test(i); // p.test expects a CAP ext Integer, gets an Integer
// ERROR!
return m2(f);
}
We could could get there by allowing the captured parameter types from S to be *supertypes of* the parameter types of T, rather than *equal to*. But there are separate reasons that allowing supertypes in full generality was rejected in the design phase of JSR 335 (for example, it allows a method reference to consider a function type more distant from its signature to be considered "more specific").
Perhaps we can enforce both, that the uncaptured function types have the same parameters, but that the captured parameter types are supertypes?
Or maybe we can come up with a way to detect that capture variables are equivalent up to renaming, or something like that?
- relates to
-
JDK-8042285 15.12.2.5: Describe treatment of generic function types
-
- Closed
-
-
JDK-8144767 Fix handling of capture variables in most-specific test
-
- Closed
-