Java 关于函数式接口 和注解的一个问题(不好意思,刚才没有用 md 的语法,排版不好) - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
yuhuzi
V2EX    问与答

Java 关于函数式接口 和注解的一个问题(不好意思,刚才没有用 md 的语法,排版不好)

 1  
  •   yuhuzi 2019-04-10 11:47:40 +08:00 2147 次点击
    这是一个创建于 2384 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我自定义一个函数接口:

    @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。 有大佬能够指点一二吗,这个问题卡在心里很不舒服。

    12 条回复    2019-04-10 15:49:36 +08:00
    gz911122
        1
    gz911122  
       2019-04-10 12:32:34 +08:00
    function.getClass().getAnnotations()
    gz911122
        2
    gz911122  
       2019-04-10 12:37:41 +08:00
    @gz911122
    少了一个 function.getMethods()
    gogotanc
        3
    gogotanc  
       2019-04-10 12:43:43 +08:00
    Method method = function.getClass().getMethod("functionA");

    Great great = method.getAnnotation(Great.class);
    kiddult
        4
    kiddult  
       2019-04-10 12:50:02 +08:00   1
    现在明白是什么情况了,你调用 functionB 的时候,参数是 functionA 的 method reference,也就是 functionB(this::functionA)?

    Java 目前没有提供 method reference 的 method literals 功能,后面可能会补上?

    如果是在调用函数之后确定类,可以在通过代理来记录,虽然就是很讨巧了
    MoHen9
        5
    MoHen9  
       2019-04-10 12:53:07 +08:00 via Android
    挺难拿到的,function 对象无法获取 functionA 方法所在 class 的信息,所以没法获取 A 方法的 method,除非你在 HandlerFunction 的方法中传一个 A 方法的 class 过去
    MoHen9
        6
    MoHen9  
       2019-04-10 12:57:23 +08:00 via Android
    不太理解什么意思,是在 HandlerFunction 的 callback 方法中执行 A 方法,然后在 B 方法中获取 A 方法的注解信息?
    yuhuzi
        7
    yuhuzi  
    OP
       2019-04-10 13:19:53 +08:00
    @kiddult 是你说的这个意思,我发现应该是 java8 不支持,不然不会这么费劲。
    SoloCompany
        8
    SoloCompany  
       2019-04-10 13:43:09 +08:00 via iPhone
    method reference 是拿不到包装的 method instance 的,而且很可能编译阶段都不会存下来,你运行时 inspect 一下 lambda object 的数据结构就清楚了
    passerbytiny
        9
    passerbytiny  
       2019-04-10 13:53:28 +08:00
    你已经把我搞糊涂了,函数式接口以及 lambda 都是用来快速定义匿名内部类的,而注解是用来标记东西的,二者用在一起很怪异,因为通常只会标记非匿名的东西,匿名的东西都是随创建随用,用完就销毁的。

    实际上,你发的代码中,完全是把 HandlerFunction 当成普通接口而非函数式接口使用。你没有贴出来 lambda 处的代码,我很怀疑你的 lambda 表达式 生成的是另一个匿名类,跟你的 functionA 没有任何关系。
    feiyuanqiu
        10
    feiyuanqiu  
       2019-04-10 13:54:18 +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
    }
    leafin
        11
    leafin  
       2019-04-10 14:44:06 +08:00
    最重要的地方,调用 functionB 的代码你没有贴出来啊老哥,虽然我猜可能是#4 说的那样。
    hpeng
        12
    hpeng  
       2019-04-10 15:49:36 +08:00
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2484 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 23ms UTC 05:18 PVG 13:18 LAX 22:18 JFK 01:18
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86