美文网首页
JDK1.7新增的MethodHandle方法与反射调用的例子

JDK1.7新增的MethodHandle方法与反射调用的例子

作者: maxbin | 来源:发表于2018-03-19 10:13 被阅读44次
    • java中通过类调用类的方法之前一直使用反射的机制去做,但是jdk1.7中增加了对动态语言的支持,增加了MethodHandle方法

    MethodHandle的Demo

    新建一个类ClassA,方法println

    public class ClassA {
        public void println(String s) {
            System.out.println(s);
        }
    }
    

    method handle方法使用

        private static MethodHandle getPrintlnMh(Object reveiver) throws NoSuchMethodException, IllegalAccessException {
            MethodType methodType = MethodType.methodType(void.class, String.class);
            return MethodHandles.lookup().findVirtual(reveiver.getClass(), "println", methodType).bindTo(reveiver);
        }
    

    MethodType.methodType()第一个参数是返回类型,第二个以后的参数是方法入参

    通过获取MethodType,调用invokeExact方法执行

        public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, Throwable {
            Object obj = new ClassA();
    
            getPrintlnMh(obj).invokeExact("MH ClassA:say hello");
    
        }
    
    • 在java代码中println方法拥有的对象必须是PrintStream的子类(实现了PrintStream接口的类),否则就算是对象确实有println(String)方法,代码依然不能运行,因为类型检查不合法。

    MethodHandle调用System.out

        public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, Throwable {
    
            Object obj = System.out;
    
            getPrintlnMh(obj).invokeExact("MH System.out:say hello");
    
        }
    

    反射调用方法

        public static void main(String[] args) {
    
            Class<?> clazz = Class.forName("com.maxbin.invoke.mh.ClassA");
    
            Method method = clazz.getDeclaredMethod("println", String.class);
    
            method.invoke(clazz.newInstance(), "invoke say hello");
    
        }
    

    反射获取的信息比MethodHandle要多。
    反射是模拟java代码层面的调用,MethodHandle是模拟字节码层面的调用。

    相关文章

      网友评论

          本文标题:JDK1.7新增的MethodHandle方法与反射调用的例子

          本文链接:https://www.haomeiwen.com/subject/zbnlqftx.html