如何获取 class (Java) 中所有方法的方法引用?
How to get Method Reference for all methods in a class (Java)?
方法参考对于Java8中的特定方法可以作为Class::Method
获得。但是如何获取一个class的所有方法的方法引用呢?
所有需要的方法都有不同的方法名称,但是相同的类型签名。此外,这些方法的名称之前未知。
示例:
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) { ... }
}
对已知方法op0
的方法引用可以通过以下方式获得:
DoubleFunction<Double> f = Test::op0;
但是,如何获取class中所有方法的方法引用?
没有反射就没有解决方案,因为现有方法的动态发现是反射操作。但是,一旦发现方法并创建了方法引用实例(或它的动态等价物),代码的实际调用将在没有反射的情况下运行:
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);
}
}
初始化 class 后,您可以使用 OPS.get(name).applyAsDouble(doubleValue)
调用不带反射的特定操作或使用
调用所有操作
OPS.forEach((name,op)-> System.out.println(name+'('+42+") => "+op.applyAsDouble(42)));
方法参考对于Java8中的特定方法可以作为Class::Method
获得。但是如何获取一个class的所有方法的方法引用呢?
所有需要的方法都有不同的方法名称,但是相同的类型签名。此外,这些方法的名称之前未知。
示例:
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) { ... }
}
对已知方法op0
的方法引用可以通过以下方式获得:
DoubleFunction<Double> f = Test::op0;
但是,如何获取class中所有方法的方法引用?
没有反射就没有解决方案,因为现有方法的动态发现是反射操作。但是,一旦发现方法并创建了方法引用实例(或它的动态等价物),代码的实际调用将在没有反射的情况下运行:
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);
}
}
初始化 class 后,您可以使用 OPS.get(name).applyAsDouble(doubleValue)
调用不带反射的特定操作或使用
OPS.forEach((name,op)-> System.out.println(name+'('+42+") => "+op.applyAsDouble(42)));