V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
yuhuzi
V2EX  ›  Java

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

  •  
  •   yuhuzi · 2019-04-10 10:37:22 +08:00 · 2179 次点击
    这是一个创建于 1814 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我自定义一个函数接口: @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。 有大佬能够指点一二吗,这个问题卡在心里很不舒服。

    10 条回复    2019-04-10 12:34:49 +08:00
    zifangsky
        1
    zifangsky  
       2019-04-10 11:10:36 +08:00
    排版太糟糕,瞬间就没有看的欲望了。
    kiddult
        2
    kiddult  
       2019-04-10 11:17:24 +08:00
    functionA 满足函数接口 HandlerFunction?

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

    注解的元数据是在方法上,不在返回值上
    feiyuanqiu
        10
    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
    }
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3227 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 14:22 · PVG 22:22 · LAX 07:22 · JFK 10:22
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.