title: LambdaMetaFactory with concrete implementation of generic type
body: <p>I am trying to use Java's <code>LambdaMetaFactory</code> to dynamically implement a generic lambda, <code>Handler&lt;RoutingContext&gt;</code>:</p>
  
  <pre><code>public class RoutingContext {
      // ...
  }
  
  @FunctionalInterface
  public interface Handler&lt;X&gt; {
      public void handle(X arg);
  }
  
  public class HomeHandler extends Handler&lt;RoutingContext&gt; {
      @Override
      public void handle(RoutingContext ctx) {
          // ...
      }
  }
  </code></pre>
  
  <p>Here is my attempt at <code>LambdaMetaFactory</code>:</p>
  
  <pre><code>try {
      Class&lt;?&gt; homeHandlerClass = HomeHandler.class;
  
      Method method = homeHandlerClass.getDeclaredMethod(
              "handle", RoutingContext.class);
      Lookup lookup = MethodHandles.lookup();
      MethodHandle mh = lookup.unreflect(method);
  
      MethodType factoryMethodType = MethodType.methodType(Handler.class);
      MethodType functionMethodType = mh.type();
      MethodHandle implementationMethodHandle = mh;
  
      Handler&lt;RoutingContext&gt; lambda =
              (Handler&lt;RoutingContext&gt;) LambdaMetafactory.metafactory(
                      lookup,
                      "handle",
                      factoryMethodType, 
                      functionMethodType,
                      implementationMethodHandle,
                      implementationMethodHandle.type()) 
              .getTarget()
              .invokeExact();
  
      lambda.handle(ctx);
  
  } catch (Throwable e) {
      e.printStackTrace();
  }
  </code></pre>
  
  <p>This gives the error:</p>
  
  <pre><code>java.lang.AbstractMethodError: Receiver class [...]$$Lambda$82/0x00000008001fa840
  does not define or inherit an implementation of the resolved method abstract
  handle(Ljava/lang/Object;)V of interface io.vertx.core.Handler.
  </code></pre>
  
  <p>I have tried a range of other options for <code>functionMethodType</code> and <code>implementationMethodHandle</code>, but have not managed to get this working yet. Also, even if I replace the <code>RoutingContext.class</code> reference with <code>Object.class</code>, this does not fix the error.</p>
  
  <p>The only way I can get the <code>lambda.handle(ctx)</code> call to succeed is by changing <code>HomeHandler</code> so that it does not extend <code>Handler</code>, making <code>HomeHandler::handle</code> static, and changing <code>RoutingContext.class</code> to <code>Object.class</code>. Oddly I can still cast the resulting lambda to <code>Handler&lt;RoutingContext&gt;</code>, even though it no longer extends <code>Handler</code>.</p>
  
  <p>My questions:</p>
  
  <ol>
  <li><p>How do I get <code>LambdaMetaFactory</code> to work with non-static methods?</p></li>
  <li><p>For this non-static SAM class <code>HomeHandler</code>, how does this work with instance allocation under the hood? Does <code>LambdaMetaFactory</code> create a single instance of the interface implementation, no matter how many method calls, since in this example there are no captured variables? Or does it create a new instance for each method call? Or was I supposed to create a single instance and pass it in to the API somehow?</p></li>
  <li><p>How do I get <code>LambdaMetaFactory</code> to work with generic methods?</p></li>
  </ol>
  
  <p>Edit: in addition to the great answers below, I came across this blog post explaining the mechanisms involved:</p>
  
  <p><a href="https://medium.freecodecamp.org/a-faster-alternative-to-java-reflection-db6b1e48c33e" rel="nofollow noreferrer">https://medium.freecodecamp.org/a-faster-alternative-to-java-reflection-db6b1e48c33e</a></p>