关于 Java 函数式编程和自定义注解的一个问题

2019-04-10 10:37:22 +08:00
 yuhuzi

我自定义一个函数接口: @FunctionalInterface public interface HandlerFunction{ void callback(); }

然后自定义了一个方法级的注解 @Great: @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Great { boolean value() default true; }

现在我给方法 A ( functionA )加上 @Great 注解,functionA 满足函数接口 HandlerFunction,再将 functionA 传到方法 B ( functionB )中去,方法 B 的参数中接收 HandlerFunction 类的方法,要如何在 functionB 中拿到 functionA 的注解 @Great 呢?代码如下:

@Greet public void functionA() { System.out.println("hello world"); }

public void functionB(HandlerFunction function) { //要如何在这里拿到传入的 function 的注解呢? function.callback(); // 回调传入的 function }

我现在 getMethod 只能拿到一个 lambda 表达式,如 function: AppTest$lambda@970,而不是具体的 functionA。 有大佬能够指点一二吗,这个问题卡在心里很不舒服。

2211 次点击
所在节点    Java
10 条回复
zifangsky
2019-04-10 11:10:36 +08:00
排版太糟糕,瞬间就没有看的欲望了。
kiddult
2019-04-10 11:17:24 +08:00
functionA 满足函数接口 HandlerFunction?

你贴这么多,还不如把代码老老实实贴一下,太乱了
yuhuzi
2019-04-10 11:38:57 +08:00
我擦,我我我打了回车的
w4ngzhen
2019-04-10 11:47:58 +08:00
@kiddult 他说的满足应该是指满足 callback 那个无参无返回的形式
passerbytiny
2019-04-10 11:53:35 +08:00
正文
可以在正文中为你要发布的主题添加更多细节。V2EX 支持 GitHub Flavored Markdown 文本标记语法。
在正式提交之前,你可以点击本页面左下角的“预览主题”来查看 Markdown 正文的实际渲染效果。
——在你发帖界面的右边又这么大一段虽然不算醒目但也不容易被忽略的话。
w4ngzhen
2019-04-10 11:57:19 +08:00
个人认为拿不到,因为这个注解加在 funcA 上,关于这个 funcA 的相关上下文应该只有持有 funcA 的类才有吧,你传方法引用那个 funcHandler 可能没有了那些上下文了。本人 Java 菜🐔一个,欢迎指正
yuhuzi
2019-04-10 12:11:03 +08:00
我已经重新发布了一个主题,排好版的
yuhuzi
2019-04-10 12:12:35 +08:00
@w4ngzhen 隐约和你感觉一样,但是对其实现机理不了解,所以不敢轻易下结论
DavidWei
2019-04-10 12:19:50 +08:00
funcB 调用的是 funcA 的返回值,在进入 funcB 之后,调用堆栈中已经不存在 funcA,且 funcA 的返回值不包含当前方法的注解信息。所以觉得拿不到。

注解的元数据是在方法上,不在返回值上
feiyuanqiu
2019-04-10 12:34:49 +08:00
拿不到,原因是 lambda 的实现方式其实是在运行时动态生成一个匿名内部类,在生成类的 callback 方法里,再去调用 functionA。

反编译 .class 可以得到这个动态生成的类:

final class Test$$Lambda$1 implements Test$HandlerFunction {
public void callback();
Code:
0: aload_0
1: getfield #15 // Field arg$1:LTest;
4: invokevirtual #26 // Method Test.functionA:()V
7: return
}

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/553621

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX