On Jan 2, 2017, at 11:33 PM, Alan Bateman <alan.bate...@oracle.com> wrote: > > On 03/01/2017 07:17, Remi Forax wrote: > >> I do not think that the workaround to create a Lookup object by reflection >> works with 9 given that java.lang.invoke is not declared as an open package. >> >> John Rose has proposed to add a method to get a private Lookup object >> through sun.misc.Unsafe but as far as i know, this proposal goes nowhere. >> > I think we got a good place with MethodHandles.privateLookupIn. It's not > going to allow you get a Lookup with private access to types in core modules > such as java.base but it may be useful for some cases.
+1 As of JDK-8130227, it is possible to use Lookup.findSpecial to gain access to interface default methods. See below for an example. — John /* $ javac InvokeDefault.java && java -ea InvokeDefault override foo on an OverridesDefault default foo on an OverridesDefault default foo on an OverridesDefault $ java version "9-ea" Java(TM) SE Runtime Environment (build 9-ea+131) Java HotSpot(TM) 64-Bit Server VM (build 9-ea+131, mixed mode) */ import java.lang.invoke.*; import static java.lang.invoke.MethodHandles.*; import static java.lang.invoke.MethodType.*; interface HasDefault { default String foo() { return "default foo on "+this; } } public class InvokeDefault { private static class OverridesDefault implements HasDefault { public String foo() { return "override foo on "+this; } public String toString() { return "an OverridesDefault"; } } public static void main(String... av) throws Throwable { HasDefault obj = new OverridesDefault(); System.out.println(obj.foo()); // ==> override foo on an OverridesDefault System.out.println(HasDefaultShim.MH_foo().invoke(obj)); // ==> default foo on an OverridesDefault System.out.println(InvokeDefault.MH_foo().invoke(obj)); // ==> default foo on an OverridesDefault } static MethodHandle MH_foo() { try { Class<?> it = HasDefault.class; MethodHandle mh = MethodHandles.lookup().findSpecial(it, "foo", methodType(String.class), it); return mh; } catch (ReflectiveOperationException ex) { throw new AssertionError(ex); } } } interface HasDefaultShim extends HasDefault { static MethodHandle MH_foo() { try { Class<?> it = HasDefault.class; Class<?> me = HasDefaultShim.class; MethodHandle mh = MethodHandles.lookup().findSpecial(me, "foo", methodType(String.class), me); assert(mh.type().parameterType(0) == me); // force the MH to accept all implementations of the interface mh = explicitCastArguments(mh, methodType(String.class, it)); assert(mh.type().parameterType(0) == it); return mh; } catch (ReflectiveOperationException ex) { throw new AssertionError(ex); } } }