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

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

  •  1
     
  •   yuhuzi Apr 10, 2019 2486 views
    This topic created in 2595 days ago, the information mentioned may be changed or developed.

    我自定义一个函数接口:

    @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 replies    2019-04-10 15:49:36 +08:00
    gz911122
        1
    gz911122  
       Apr 10, 2019
    function.getClass().getAnnotations()
    gz911122
        2
    gz911122  
       Apr 10, 2019
    @gz911122
    少了一个 function.getMethods()
    gogotanc
        3
    gogotanc  
       Apr 10, 2019
    Method method = function.getClass().getMethod("functionA");

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

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

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

    实际上,你发的代码中,完全是把 HandlerFunction 当成普通接口而非函数式接口使用。你没有贴出来 lambda 处的代码,我很怀疑你的 lambda 表达式 生成的是另一个匿名类,跟你的 functionA 没有任何关系。
    feiyuanqiu
        10
    feiyuanqiu  
       Apr 10, 2019
    怎么又来一个帖子...在另外一个帖子回复了,这里粘贴一下:

    拿不到,原因是 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  
       Apr 10, 2019
    最重要的地方,调用 functionB 的代码你没有贴出来啊老哥,虽然我猜可能是#4 说的那样。
    hpeng
        12
    hpeng  
       Apr 10, 2019
    About     Help     Advertise     Blog     API     FAQ     Solana     2977 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 45ms UTC 13:01 PVG 21:01 LAX 06:01 JFK 09:01
    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