很多开发场景需要用到Java Bean的属性名,直接写死属性名字符串的形式容易产生bug(属性名一旦变化,IDE不会告诉你你的字符串需要同步修改)。JDK8的Lambda可以通过方法引用简化代码,同样也可以通过getter/setter的方法引用拿到属性名,避免潜在的bug。

期望实现效果

// 传统方式:hard code写死属性名
// String ITEM_NAME = "orgName";
// 方法引用:替代hard code字符串,当属性名变化时IDE会同步提示,避免未同步产生bug
String ITEM_NAME = BeanUtils.convertToFieldName(User::getOrgName);

具体实现代码封装

1. 定义FunctionalInterface 接收方法引用

/*** getter方法接口定义*/
@FunctionalInterface
public interface IGetter<T> extends Serializable {Object apply(T source);
}
/*** setter方法接口定义*/
@FunctionalInterface
public interface ISetter<T, U> extends Serializable {void accept(T t, U u);
}

2. 定义getter/setter引用转换属性名的工具类

public class BeanUtils {.../*** 缓存类-Lambda的映射关系*/private static Map<Class, SerializedLambda> CLASS_LAMDBA_CACHE = new ConcurrentHashMap<>();/**** 转换方法引用为属性名* @param fn* @return*/public static <T> String convertToFieldName(IGetter<T> fn) {SerializedLambda lambda = getSerializedLambda(fn);String methodName = lambda.getImplMethodName();String prefix = null;if(methodName.startsWith("get")){prefix = "get";}else if(methodName.startsWith("is")){prefix = "is";}if(prefix == null){log.warn("无效的getter方法: "+methodName);}// 截取get/is之后的字符串并转换首字母为小写(S为diboot项目的字符串工具类,可自行实现)return S.uncapFirst(S.substringAfter(methodName, prefix));}/**** 转换setter方法引用为属性名* @param fn* @return*/public static <T,R> String convertToFieldName(ISetter<T,R> fn) {SerializedLambda lambda = getSerializedLambda(fn);String methodName = lambda.getImplMethodName();if(!methodName.startsWith("set")){log.warn("无效的setter方法: "+methodName);}// 截取set之后的字符串并转换首字母为小写(S为diboot项目的字符串工具类,可自行实现)return S.uncapFirst(S.substringAfter(methodName, "set"));}/**** 获取类对应的Lambda* @param fn* @return*/private static SerializedLambda getSerializedLambda(Serializable fn){//先检查缓存中是否已存在SerializedLambda lambda = CLASS_LAMDBA_CACHE.get(fn.getClass());if(lambda == null){try{//提取SerializedLambda并缓存Method method = fn.getClass().getDeclaredMethod("writeReplace");method.setAccessible(Boolean.TRUE);lambda = (SerializedLambda) method.invoke(fn);CLASS_LAMDBA_CACHE.put(fn.getClass(), lambda);}catch (Exception e){log.error("获取SerializedLambda异常, class="+fn.getClass().getSimpleName(), e);}}return lambda;}
}

3. 开心的引用

String ITEM_NAME = BeanUtils.convertToFieldName(User::getOrgName);

Diboot - 简单高效的轻代码开发框架

利用Lambda实现通过getter/setter方法引用拿到属性名相关推荐

  1. lambda表达式与6种方法引用格式

    继JDK 1.8之后,更新了lambda的新特性 lambda是一种强调做什么,而不是用什么去做的语法 而匿名内部类则是强调如何去做,用了什么去做这件事的语法 函数式接口:有且仅有一个抽象方法的接口, ...

  2. 方法引用_通过对象名引用成员方法

    方法引用符 双冒号:: 为引用运算符,而它所在的表达式被称为方法引用.如果Lambda要表达的函数方案已经存在于某个方 法的实现中,那么则可以通过双冒号来引用该方法作为Lambda的替代者. 语义分析 ...

  3. Java利用PropertyDescriptor获取属性的 getter/setter 方法

    PropertyDescriptor类: PropertyDescriptor类表示JavaBean类通过存储器导出一个属性.主要方法:     1. getReadMethod(),获得用于读取属性 ...

  4. 还在手写 Getter/Setter 方法吗?Lombok 让你的代码更简洁!

    以下是文章大纲: Lombok 是什么? 官网:https://projectlombok.org/ Lombok 是一个 Java 库,使用 Lombok 可以通过简单的注解帮助我们消除 Java ...

  5. 十三、Java高级特性 Lambda表达式 | 接口组成更新 | 方法引用 | 函数式接口

    文章目录 十三.Java高级特性 1.Lambda表达式 1.1体验Lambda表达式[理解] 1.2Lambda表达式的标准格式[理解] 1.3Lambda表达式练习1[应用] 1.4Lambda表 ...

  6. 函数式编程-Stream流/lambda表达式/Optional/函数式接口/方法引用/高级用法

    函数式编程-Stream流 不会Lambda表达式.函数式编程?你确定能看懂公司代码?-java8函数式编程(Lambda表达式,Optional,Stream流)从入门到精通-最通俗易懂 1. 概述 ...

  7. Java中getter/setter方法的使用和解析

    1.怎么生成getter方法和setter方法 第一步:在类里面设置几个属性值. 第二布:同时按住alt+insert 快捷键,生产对应属性的setter和getter方法 第三步:选中想要的方法即可 ...

  8. 通过PropertyDescriptor反射获取属性的 getter/setter 方法

              Java类中的私有的(private)属性是获取不到的(即使使用继承依然获取不到),那如果非要获取私有属性的值怎么办呢?一般的做法是将该java类封装称为一个JavaBean,即封 ...

  9. C++工作笔记-getter/setter方法中大佬的风格

    今天看了Qt官方文档,发现大佬都是这样写代码的, 用更新了我对编码风格的认识, 代码如下: #include <iostream> #include <string> usin ...

最新文章

  1. 人人须知的 jQuery 技巧
  2. STM32使用串口IDLE中断的两种接收不定长数据的方式
  3. Angular2 - [innerHTML] pipe(把字符串里的 /n 替换成 <br/>)
  4. linux 性能测试iostat,Linux性能分析之二(iostat)
  5. mysql慢查询日志轮转_MySQL slow log相关参数解释
  6. Android和.NET通用的AES算法
  7. 【机器人】项目疑难杂症
  8. Xcode8 NSLog打印json不全解决办法
  9. 面试官上来就问:能不能开发一个微信朋友圈、推特?我有点懵~
  10. linux各个目录作用详解,linux各个目录作用
  11. windows异常捕获生成minidump windows
  12. tcptracerte参数_CCNA安全题库
  13. 本科生计算机论文中文核心,本科生可以发表核心期刊论文吗
  14. 蛇形字符串、驼峰字符串转换
  15. 第四章第九节数据资产盘点-数据资产目录分类
  16. 单元测试的基本概念和核心技法
  17. socket编程 error: storage size of ‘sockAddr’ isn’t known
  18. Notepad++常用插件下载地址
  19. Laravel框架-迁移文件
  20. python polygon_在Python中将Multipolygon转换为Polygon - python

热门文章

  1. 【关于我第一次上python课的感想】
  2. 山区灭火机器人_帅气!池州市首台消防灭火机器人正式投入基层执勤
  3. android qq隐藏功能,90﹪的人都不知道--手机QQ这些隐藏的功能!
  4. 奇瑞新能源的小车为何备受市场青睐?鲍思语这样解释
  5. 【人工智能 AI】机器学习快速入门教程(Google)
  6. 规则引擎解决方案浅析
  7. 新手如何第一次编写 “Hello World“ Windows 驱动程序 (KMDF)
  8. 华为高清会议摄像机预置位的使用方法
  9. 电视剧《大秧歌》随感
  10. Ubuntu20.04安装CUDA+CUDNN+Conda+PyTorch