Proposal: java.lang.reflect.Proxy and default methods
Peter Levart
peter.levart at gmail.com
Sun Jun 5 07:43:47 UTC 2016
Hi Jake,
On 06/05/2016 08:28 AM, Jake Wharton wrote:
> On Fri, Jun 3, 2016 at 10:58 AM Peter Levart <peter.levart at gmail.com
> <mailto:peter.levart at gmail.com>> wrote:
>
> InvocationHandler gets invoked for default methods, but it
> has not provision to forward such calls to the default implementations
> in the interfaces.
>
>
> This isn't quite true. You can use MethodHandles to invoke the default
> method if the interface is public:
>
> Object returnValue = MethodHandles.lookup()
> .in(declaringClass)
> .unreflectSpecial(method, declaringClass)
> .bindTo(proxy)
> .invokeWithArguments(args);
You are right. It appears that such Lookup has more powers than bytecode.
>
> If the interface is not public, things get a bit more tricky since you
> need an instance which ignores the visibility. The only way to get at
> this is through creating your own trusted instance for the interface type:
>
> Constructor<Lookup> constructor =
> Lookup.class.getDeclaredConstructor(Class.class, int.class);
> constructor.setAccessible(true);
> Object returnValue = constructor.newInstance(declaringClass, -1 /*
> trusted */)
> .unreflectSpecial(method, declaringClass)
> .bindTo(proxy)
> .invokeWithArguments(args);
>
> That said, I'm all for an API that makes this easier! Please make sure
> it handles non-public interface types as well.
Right, the changes I made to Proxy class generation, construct the
Lookup object in the proxy class' <clinit>. Such Lookup has access to
any superinterface method by virtue of the proxy class being able to
implement such interface (if it is a package-private interface, the
proxy class is generated in the same package; if it is an interface in a
non-exported package, the proxy class is generated in a dynamic module
and qualified export is added to the module holding the interface; etc...).
Regards, Peter
More information about the core-libs-dev
mailing list