4

MethodHandle 的 Java 文档说私有方法应该通过 findSpecial 调用。但是在下面的示例中,我可以通过 findVirtual 调用它。

有人可以解释一下我在这里缺少什么吗?

 import java.lang.invoke.MethodHandles;
import java.lang.invoke.*;

import java.lang.invoke.MethodType;

public class PrivateClassMethodLookupTest{
    public static void main(String[] args) throws Throwable{
     new PrivateClassMethodLookupTest().m();
     MethodHandle mh =   MethodHandles.lookup()
                .findVirtual(PrivateClassMethodLookupTest.class, "m", MethodType.methodType(void.class));
      mh.invoke(new PrivateClassMethodLookupTest());
    }

    private void m() { System.out.println("in m");}
}
4

1 回答 1

1

您可以调用它,因为您可以访问同一类的私有方法,该类main正在运行尝试运行以下代码:

package com.company;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;

public class PrivateClassMethodLookupTest {
    public static void main(String[] args) throws Throwable {
        new PrivateClassMethodLookupTest.Inner().m();
        MethodHandle mh = MethodHandles.lookup()
                .findVirtual(PrivateClassMethodLookupTest.Inner.class, "m", MethodType.methodType(void.class));
        mh.invoke(new PrivateClassMethodLookupTest.Inner());
    }

    static class Inner {
        private void m() {
            System.out.println("in m");
        }
    }
}

要调用私有方法,您应该使用反射 API 并更改方法访问类型:

package com.company;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Method;

public class PrivateClassMethodLookupTest {
    public static void main(String[] args) throws Throwable {
        new PrivateClassMethodLookupTest.Inner().m();
        Method declaredMethod = PrivateClassMethodLookupTest.Inner.class.getDeclaredMethod("m");
        declaredMethod.setAccessible(true);
        MethodHandle mh = MethodHandles.lookup().unreflect(declaredMethod);
        mh.invoke(new PrivateClassMethodLookupTest.Inner());
    }

    static class Inner {
        private void m() {
            System.out.println("in m");
        }
    }
}
于 2016-01-13T10:19:47.083 回答