例如:
@FunctionalInterface
public interface MyRPC {
Object execute(Object input);
}
public class MyImpl{
public Object rpc1(Object input) {
System.out.Println(input)
return 100;
}
public static Object invokeRpc(MyRPC rpc, Object input) {
// TODO: How can I get the name of the method passed in, like "rpc1" or "MyImpl::rpc1" here?
return rpc.execute(input);
}
public static void main(String[] args) {
final MyWfImpl myc = new MyWfImpl();
invokeRpc(myc::rpc1, 1)
}
}
在invokeRpc
中,我如何获得rpc名称,如"rpc1"或"MyImpl: rpc1" ?
你不能那样做。lambda不以一种你可以访问的方式携带这些信息。
这是可行的,但只能通过一个hack,所以不能保证它在每个VM上都能工作。
有了这些,下面是如何做到这一点:
1。使您的功能界面扩展Serializable
:
@FunctionalInterface
public interface MyRPC extends Serializable {
Object execute(Object input);
}
它的实例现在将有一个名为writeReplace
的内部方法,可用于提取包含元数据的SerializedLambda
。
2。从SerializedLambda
中提取类/方法信息(您可以将代码添加到某些实用程序类或功能接口本身):
@FunctionalInterface
public interface MyRPC extends Serializable {
Object execute(Object input);
default SerializedLambda serialized() {
try {
Method replaceMethod = getClass().getDeclaredMethod("writeReplace");
replaceMethod.setAccessible(true);
return (SerializedLambda) replaceMethod.invoke(this);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
default String getImplClassName() {
return serialized().getImplClass().replaceAll("/", ".");
}
default String getImplMethodName() {
return serialized().getImplMethodName();
}
}
3。享受你的hackery的果实:
public static Object invokeRpc(MyRPC rpc, Object input) {
System.out.println(rpc.getImplMethodName()); //🥳
return rpc.execute(input);
}