Quantcast
Channel: Active questions tagged methodhandle - Stack Overflow
Viewing all articles
Browse latest Browse all 37

Why does LambdaMetafactory fail when using a custom functional interface (but Function works fine)?

$
0
0

Given:

import java.lang.invoke.LambdaMetafactory;import java.lang.invoke.MethodHandle;import java.lang.invoke.MethodHandles;import java.lang.invoke.MethodType;import java.util.function.Function;class Testcase{    @FunctionalInterface    public interface MyBuilder1<R>    {        R apply(String message);    }    @FunctionalInterface    public interface MyBuilder2<R>    {        R apply(Object message);    }    public static void main(String[] args) throws Throwable    {        Class<?> clazz = IllegalArgumentException.class;        MethodHandles.Lookup lookup = MethodHandles.lookup();        MethodHandle mh = lookup.findConstructor(clazz, MethodType.methodType(void.class, String.class));        MethodHandle myFunctionConstructor = LambdaMetafactory.metafactory(            lookup,"apply",            MethodType.methodType(Function.class),            mh.type().erase(),            mh,            mh.type()        ).getTarget();        MethodHandle myBuilderConstructor1 = LambdaMetafactory.metafactory(            lookup,"apply",            MethodType.methodType(MyBuilder1.class),            mh.type().erase(),            mh,            mh.type()        ).getTarget();        MethodHandle myBuilderConstructor2 = LambdaMetafactory.metafactory(            lookup,"apply",            MethodType.methodType(MyBuilder2.class),            mh.type().erase(),            mh,            mh.type()        ).getTarget();        @SuppressWarnings("unchecked")        Function<String, IllegalArgumentException> functionFactory =            (Function<String, IllegalArgumentException>) myFunctionConstructor.invokeExact();        @SuppressWarnings("unchecked")        MyBuilder1<IllegalArgumentException> myBuilder1Factory =            (MyBuilder1<IllegalArgumentException>) myBuilderConstructor1.invokeExact();        @SuppressWarnings("unchecked")        MyBuilder2<IllegalArgumentException> myBuilder2Factory =            (MyBuilder2<IllegalArgumentException>) myBuilderConstructor2.invokeExact();        IllegalArgumentException runFunction = functionFactory.apply("test");//      IllegalArgumentException runBuilder1 = myBuilder1Factory.apply("test");        IllegalArgumentException runBuilder2 = myBuilder2Factory.apply("test");    }}

Why do runFunction and runBuilder2 work while runBuilder1 throws the following exception?

java.lang.AbstractMethodError: Receiver class Testcase$$Lambda$233/0x0000000800d21d88 does not define or inherit an implementation of the resolved method 'abstract java.lang.Object apply(java.lang.String)' of interface MyBuilder1.

Given that the IllegalArgumentException constructor takes a String parameter, not an Object, shouldn't the JVM accept runBuilder1 and complain about the parameter type of the other two?


Viewing all articles
Browse latest Browse all 37

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>