Invoke méthode privée par Java ASM

user12801918:

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?

Holger:

Le défi est de ne pas générer une classe invoquant la privatemé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.Unsafequi 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 privateméthodes de synthèse de maintien du corps d'une expression lambda.

Vous pouvez utiliser cette option pour charger votre bytecode, en utilisant la privateclasse 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 getDeclaredFields0sans réflexion.

privateLookupInest une méthode Java 9 qui fonctionnera si vous êtes dans le code non modulaire ou de fournir le nécessaire l' --add-opensoption 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 Lookupclasse pour obtenir une instance de consultation appropriée. Cette réponse montre une solution, voici une autre approche.

Je suppose que tu aimes

Origine http://10.200.1.11:23101/article/api/json?id=478792&siteId=1
conseillé
Classement