Je voudrais invoquer une méthode privée sans utiliser la réflexion: est-il possible de brancher une méthode native privée en utilisant ASM et l'invoquons?
Le défi est de ne pas générer une classe invoquant la private
méthode via ASM ou un analogue outil de génération de code intermédiaire. Le défi est d'obtenir le bytecode dans la machine virtuelle Java sans être rejeté par le vérificateur.
Pour OpenJDK / HotSpot, il est sun.misc.Unsafe
qui présente la méthode defineAnonymousClass(Class<?>, byte[], Object[])
qui est utilisée pour générer des classes d'accesseurs, comme les classes d'exécution d' application interfaces fonctionnelles et invoquer les private
méthodes de synthèse de maintien du corps d'une expression lambda.
Vous pouvez utiliser cette option pour charger votre bytecode, en utilisant la private
classe déclarant de la méthode comme premier argument, pour rendre la méthode accessible. D'autre part, le propre cas d'utilisation de JRE implique que vous ne même pas besoin de générer de tels bytecode vous:
MethodHandles.Lookup l = MethodHandles.privateLookupIn(Class.class, MethodHandles.lookup());
MethodHandle target = l.findSpecial(Class.class, "getDeclaredFields0",
MethodType.methodType(Field[].class, boolean.class), Class.class);
BiFunction<Class<?>,Boolean,Field[]> a = (BiFunction)LambdaMetafactory.metafactory(
l, "apply", MethodType.methodType(BiFunction.class), target.type().generic(),
target, target.type().changeParameterType(1, Boolean.class))
.getTarget().invokeExact();
Ensuite, vous pouvez appeler, par exemple , a.apply(Class.class, false)
qui appellera getDeclaredFields0
sans réflexion.
privateLookupIn
est une méthode Java 9 qui fonctionnera si vous êtes dans le code non modulaire ou de fournir le nécessaire l' --add-opens
option au démarrage de la JVM, pour ouvrir java.base
à votre module. Il y aura un avertissement sur l'accès de réflexion et bien, il a raison de noter que cet accès « sera refusée dans un communiqué de l' avenir ». Quoi qu'il en soit, Comment cacher avertissement « accès illégal réflexion » en java 9 sans argument JVM? pourrait être intéressant.
Pour Java 8, vous aurez besoin de pirater la Lookup
classe pour obtenir une instance de consultation appropriée. Cette réponse montre une solution, voici une autre approche.