Java8获取lambda方法引用传入的方法名

java8的lambda表达式极大的简化了我们的代码,其中方法引用(method reference)更是增加了代码的可(zhuang)读(bi)性和进一步简化了代码。本文将通过简单的例子介绍如何获取方法引用传入的方法名和类名。

一、需求

在之前的文章中我们通过反射的方式编写了一个空值校验器。使用方式如下:

        check(user,"username","pasword");

这样的空值校验器在使用中会带来两个问题:
1、字符串容易输入错误,并且难以debug
(例如上面的password写成了pasword)
2、当对应model修改的时候不能同步的去更新对应的方法,或者容易产生遗漏

针对以上问题,
我们希望实现的效果:

        check(user::getUsername, user::getPassword);

二、直接上代码

首先定义一个函数式接口:

//函数式接口注解
@FunctionalInterface
public interface Function extends Serializable {
    //这里只接收无参方法
    Object get();

    //这个方法返回的SerializedLambda是重点
    default SerializedLambda getSerializedLambda() throws Exception {
        //writeReplace改了好像会报异常
        Method write = this.getClass().getDeclaredMethod("writeReplace");
        write.setAccessible(true);
        return (SerializedLambda) write.invoke(this);
    }

    default String getImplClass() {
        try {
            return getSerializedLambda().getImplClass();
        } catch (Exception e) {
            return null;
        }
    }

    default String getImplMethodName() {
        try {
            return getSerializedLambda().getImplMethodName();
        } catch (Exception e) {
            return null;
        }
    }
}

写一个以Function接口为参数的check方法,使用可变参数可以使方法更灵活

    public static void check(Function... functions) {
        for (Function fun : functions) {
            System.out.println("传入的实现类:" + fun.getImplClass());
            System.out.println("传入的方法名:" + fun.getImplMethodName());
            System.out.println("传入的参数值:" + fun.get());
            System.out.println("传入数据类型:" + fun.get().getClass());
        }
    }

写一个main方法并调用:

    public static void main(String[] args) {

        User user = new User()
                .setUsername("123")
                .setPassword("456");

        check(user::getUsername, user::getPassword);
    }

调用结果:
调用结果
这样就可以获得lambda方法引用的参数名了

需要注意的是,这样的写法是不能获取正确信息的:

        check(()->user.getUsername());

三、关于SerializedLambda

仔细观察函数式接口Function,我们继承了Serializable接口,使得Function接口可以序列化。而SerializedLambda是java8提供的一个新的类,继承了Serializable的函数式接口的实例可以获取一个属于它的SerializedLambda实例,SerializedLambda封装了原传入函数的一些信息,这样我们就可以通过SerializedLambda获取到方法的名称,类名等信息了。

关于SerializedLambda更多的方法可参考

本文到此结束,谢谢浏览!!

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值