자바 ASM에 의해 전용 메서드 호출

user12801918 :

것이 가능은 ASM과있는 invoke를 사용하여 개인 네이티브 메소드 후크 : 난 반사를 사용하지 않고 개인 메소드를 호출 하시겠습니까?

홀거 :

문제는 호출하는 클래스 생성되지 privateASM 통한 방법 또는 유사한 바이트 코드 생성 도구. 문제는 검증 거부하지 않고 JVM에 바이트 코드를 얻는 것입니다.

오픈 JDK / 핫스팟, 거기 sun.misc.Unsafe에있어서 가지는 defineAnonymousClass(Class<?>, byte[], Object[]), 접근 클래스를 생성하는 클래스 실행 기능 인터페이스를 구현하는 것처럼 상기 호출에 사용되는 private람다 식의 신체를 유지 합성 방법.

당신은 사용하여 바이트 코드를로드하려면이 옵션을 사용할 수있는 private방법에 액세스 할 수 있도록하기 위해, 첫 번째 인수로 메소드의 선언 클래스를. 한편, JRE의 자신의 사용 사례는 심지어 바이트 코드를 직접 생성 할 필요가 없습니다 것을 의미한다 :

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();

그렇다면, 당신은 예를 들어, 호출 할 수 a.apply(Class.class, false)호출합니다 getDeclaredFields0반영하지 않고.

privateLookupIn당신이 비 모듈 코드에있어 또는 필요한 제공하는 경우 작동 자바 (9) 방법 --add-opens열, JVM 시작시 옵션을 java.base모듈에. 거기에 반사 액세스에 대한 경고하고 잘, 그러한 액세스가 "미래의 릴리스에서 거부됩니다"라는 지적에 대해 권리 것입니다. 어쨌든, 어떻게 JVM 인수없이 자바 9 "잘못된 반사 액세스"경고 숨기려면? 흥미로운 일이 될 수 있습니다.

자바 8의 경우 해킹해야 할 것 Lookup적절한 조회 인스턴스를 얻을 클래스입니다. 이 답변은 , 해결책을 보여줍니다 여기에 또 다른 접근 방법이다.

추천

출처http://10.200.1.11:23101/article/api/json?id=478788&siteId=1