How to get Method Reference for all methods in a class (Java)?

ε祈祈猫儿з 提交于 2019-12-04 16:28:47

There is no solution that works without Reflection as the dynamic discovery of existing methods is a reflective operation. However, once methods are discovered and a method reference instance (or the dynamic equivalent of it) has been created, the actual invocation of the code runs without Reflection:

class Test {
    public static double op0(double a) { ... }
    public static double op1(double a) { ... }
    public static double op2(double a) { ... }
    public static double op3(double a) { ... }
    public static double op4(double a) { ... }

    static final Map<String, DoubleUnaryOperator> OPS;
    static {
        HashMap<String, DoubleUnaryOperator> map=new HashMap<>();
        MethodType type=MethodType.methodType(double.class, double.class);
        MethodType inT=MethodType.methodType(DoubleUnaryOperator.class);
        MethodHandles.Lookup l=MethodHandles.lookup();
        for(Method m:Test.class.getDeclaredMethods()) try {
          if(!Modifier.isStatic(m.getModifiers())) continue;
          MethodHandle mh=l.unreflect(m);
          if(!mh.type().equals(type)) continue;
          map.put(m.getName(), (DoubleUnaryOperator)LambdaMetafactory.metafactory(
            l, "applyAsDouble", inT, type, mh, type).getTarget().invokeExact());
        } catch(Throwable ex) {
            throw new ExceptionInInitializerError(ex);
        }
        OPS=Collections.unmodifiableMap(map);
    }
}

Once the class has been initialized, you can invoke a particular op without Reflection using OPS.get(name).applyAsDouble(doubleValue) or invoke all ops using, e.g.

OPS.forEach((name,op)-> System.out.println(name+'('+42+") => "+op.applyAsDouble(42)));
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!