Search code examples
javareflectionjava-8methodhandle

Combining MethodHandles.publicLookup() with Method.setAccessible(true)


I understand that publicLookup() is faster than a lookup() for public methods, and I would like to make use of that. If I was to use MethodHandles.publicLookup().unreflect(Method) on a Method which is not inherently public but I have called setAccessible(true) on, would it work?


Solution

  • Since a Method on which setAccessible(true) has been successfully invoked can be called by everyone, it can made unreflected using the MethodHandles.publicLookup() like with any other Lookup object.

    After all, it’s the only way to use access override with MethodHandles as java.lang.invoke does not offer any access override feature on its own.

    The following demonstration uses a Field rather than a Method but has an impressive result:

    Field m = String.class.getDeclaredField("value");
    m.setAccessible(true);
    MethodHandle mh = MethodHandles.publicLookup().unreflectGetter(m);
    char[] ch = (char[])mh.invoke("hello");
    Arrays.fill(ch, '*');
    System.out.println("hello");