Lambda and wildcard
Tagir Valeev
amaembo at gmail.com
Tue Oct 7 19:52:57 UTC 2025
On Tue, Oct 7, 2025, 21:05 Tagir Valeev <amaembo at gmail.com> wrote:
> Hello!
>
> The 'makeX' method in my example is not generic, so this part of the
> specification looks unrelated.
>
A correction: I meant that the method 'get' of the 'Supplier' functional
interface is not generic.
> With best regards,
> Tagir Valeev
>
> On Tue, Oct 7, 2025, 18:41 Glavo <zjx001202 at gmail.com> wrote:
>
>> Hi Tagir,
>>
>> This is expected behavior. See Chapter 15 of the Java Language
>> Specification (Java SE 25 Edition) [1]:
>>
>> Unlike a lambda expression, a method reference can be congruent with a
>> generic function type (that is, a function type that has type parameters).
>> This is because the lambda expression would need to be able to declare
>> type parameters, and no syntax supports this; while for a method reference,
>> no such declaration is necessary. For example, the following program is
>> legal:
>>
>> interface ListFactory {
>> <T> List<T> make();
>> }
>>
>> ListFactory lf = ArrayList::new;
>> List<String> ls = lf.make();
>> List<Number> ln = lf.make();
>>
>>
>> Glavo
>>
>> [1]:
>> https://docs.oracle.com/javase/specs/jls/se25/html/jls-15.html#jls-15.27
>>
>> On Wed, Oct 8, 2025 at 12:12 AM Tagir Valeev <amaembo at gmail.com> wrote:
>>
>>> Hello!
>>>
>>> I'm investigating a seemingly weird compilation case. Consider the
>>> following Java interface:
>>>
>>> import java.util.function.Supplier;
>>>
>>> interface Main {
>>> interface X<T> {
>>> X<T> self();
>>> }
>>>
>>> static X<?> makeX() {return null;}
>>>
>>> static <R> X<R> create(Supplier<? extends R> supplier) {return null;}
>>>
>>> static X<X<?>> methodRef() {
>>> return create(Main::makeX).self();
>>> }
>>>
>>> static X<X<?>> lambda() {
>>> return create(() -> makeX()).self();
>>> }
>>> }
>>>
>>> I expect that either both methods 'methodRef' and 'lambda' should be
>>> compilable or both should be non-compilable. However, while 'methodRef'
>>> compiles, 'lambda' is rejected by compiler (using javac build 25+36-3489):
>>>
>>> Main.java:17: error: incompatible types: X<X<CAP#1>> cannot be converted
>>> to X<X<?>>
>>> return create(() -> makeX()).self();
>>> ^
>>> where CAP#1 is a fresh type-variable:
>>> CAP#1 extends Object from capture of ?
>>> 1 error
>>> error: compilation failed
>>>
>>> Could you please help me and clarify whether this is an expected
>>> behavior or not?
>>>
>>> With best regards,
>>> Tagir Valeev
>>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/compiler-dev/attachments/20251007/3ed50a0a/attachment.htm>
More information about the compiler-dev
mailing list