在编码时经常会用到同名的属性名字符串,比如

  1. 用相同的属性名做为 map 中的键;
  2. 在 mybatis 中,根据属性名的下划线字符串来拼接 sql 查询条件。

需要修改属性名时,如果是用字符串硬编码的,引用的地方越多,修改越困难

但是如果用的是 java8 中的属性引用,操作起来就很方便了,修改一处即可修改全部相关引用。

属性工具类测试

参考下面测试类,怎样使用;

如果想要修改 articleName articleTitle

在 IDEA 中,修改类的属性名很方便,选中属性名 articleName,按下快捷键 <Shift + F6>,键入新的属性名称 articleTitle,确认即可替换所有关联的属性名称

import lombok . Getter ; import lombok . Setter ; * 属性工具类测试 * @author lilou public class FieldUtilTest { @Setter @Getter static class Article { String articleName ; String articleContent ; public static void main ( String [ ] args ) { // test getter System . out . println ( FieldUtil . noPrefix ( Article : : getArticleName ) ) ; System . out . println ( FieldUtil . underline ( Article : : getArticleName ) ) ; System . out . println ( FieldUtil . underlineUpper ( Article : : getArticleContent ) ) ; System . out . println ( FieldUtil . toSymbolCase ( Article : : getArticleName , '$' ) ) ; // test setter System . out . println ( FieldUtil . noPrefix ( Article : : setArticleName ) ) ; System . out . println ( FieldUtil . underline ( Article : : setArticleName ) ) ; System . out . println ( FieldUtil . underlineUpper ( Article : : setArticleContent ) ) ; System . out . println ( FieldUtil . toSymbolCase ( Article : : setArticleName , '$' ) ) ;

属性工具类代码

关键逻辑是利用了 java8 中的 SerializedLambda 的 getImplMethodName 方法来获取属性名。

源码中引用了 hutool 第三方工具类的 StrUtil 工具,方便操作字符串,当然也可自行开发。

参考资料: 利用 Lambda 实现通过 getter/setter 方法引用拿到属性名 - SegmentFault 思否

import cn . hutool . core . util . StrUtil ; import java . io . Serializable ; import java . lang . invoke . SerializedLambda ; import java . lang . reflect . Method ; * 属性工具类,用来获取 Getter 和 Setter 属性的名称。支持首字母小写样式,下划线的样式和自定义样式 * 参考:[利用Lambda实现通过getter/setter方法引用拿到属性名 - SegmentFault 思否](https://segmentfault.com/a/1190000019389160) * @author lilou public class FieldUtil { * ===========> getter 方法引用 <=========== * 下划线样式,小写 public static < T > String underline ( IGetter < T > fn ) { return toSymbolCase ( fn , '_' ) ; * 下划线样式,大写 public static < T > String underlineUpper ( IGetter < T > fn ) { return underline ( fn ) . toUpperCase ( ) ; * 依据符号转换样式 public static < T > String toSymbolCase ( IGetter < T > fn , char symbol ) { return StrUtil . toSymbolCase ( noPrefix ( fn ) , symbol ) ; * 转换getter方法引用为属性名,首字母小写 public static < T > String noPrefix ( IGetter < T > fn ) { return getGeneralField ( fn ) ; * ===========> setter 方法引用 <=========== * 下划线样式,小写 public static < T , R > String underline ( ISetter < T , R > fn ) { return toSymbolCase ( fn , '_' ) ; * 下划线样式,大写 public static < T , R > String underlineUpper ( ISetter < T , R > fn ) { return underline ( fn ) . toUpperCase ( ) ; * 依据符号转换样式 public static < T , R > String toSymbolCase ( ISetter < T , R > fn , char symbol ) { return StrUtil . toSymbolCase ( noPrefix ( fn ) , symbol ) ; * 转换setter方法引用为属性名,首字母小写 public static < T , R > String noPrefix ( ISetter < T , R > fn ) { return getGeneralField ( fn ) ; * ===========> 复用功能 <=========== * 获得set或get或is方法对应的标准属性名,其它前缀的方法名使用原名 private static String getGeneralField ( Serializable fn ) { SerializedLambda lambda = getSerializedLambda ( fn ) ; String getOrSetMethodName = lambda . getImplMethodName ( ) ; final String generalField = StrUtil . getGeneralField ( getOrSetMethodName ) ; return StrUtil . isEmpty ( generalField ) ? getOrSetMethodName : generalField ; * 获取类对应的Lambda private static SerializedLambda getSerializedLambda ( Serializable fn ) { //先检查缓存中是否已存在 SerializedLambda lambda ; try { //提取SerializedLambda并缓存 Method method = fn . getClass ( ) . getDeclaredMethod ( "writeReplace" ) ; method . setAccessible ( Boolean . TRUE ) ; lambda = ( SerializedLambda ) method . invoke ( fn ) ; } catch ( Exception e ) { throw new IllegalArgumentException ( "获取SerializedLambda异常, class=" + fn . getClass ( ) . getSimpleName ( ) , e ) ; return lambda ; * 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 ) ; 背景在编码时经常会用到同名的属性名字符串,比如用相同的属性名做为 map 中的键;在 mybatis 中,根据属性名的下划线字符串来拼接 sql 查询条件。需要修改属性名时,如果是用字符串硬编码的,引用的地方越多,修改越困难但是如果用的是 java8 中的属性引用,操作起来就很方便了,修改一处即可修改全部相关引用。属性工具类测试参考下面测试类,怎样使用;如果想要修改 articleName 为 articleTitle,在 IDEA 中,修改类的属性名很方便,选中属性名 articl
在我们 开发 过程中常常有一个需求,就是要知道实体类中Getter方法对应的 属性 称(Field Name),例如实体类 属性 到数据库字段的映射,我们常常是硬编码指定 属性 ,这种硬编码有两个缺点。 1、编码效率低:因为要硬编码写 属性 ,很可能写错,需要非常小心,时间浪费在了不必要的检查上。 2、容易让 开发 人员踩坑:例如有一天发现实体类中Field Name定义的不够明确,希望换一个Field Name...
package cn.com.hisserver.util; import java .lang.reflect.Field; import java .lang.reflect.Method; import java .util.ArrayList; import java .util.HashMap; import java .util.List; import java .
Java 实体转换的 工具类 主要是用来方便地进行不同实体类之间的转换操作。在 开发 过程中,我们通常会涉及到不同层之间的数据传递,比如数据库实体类与前端展示实体类之间的转换,或者接口请求实体类与数据库实体类之间的转换等。 这些实体类之间的 属性 可能会存在一些差异,比如 属性 不一致、 属性 类型不一致等,因此需要编写一些代码来手动进行 属性 的赋值,这样就会导致代码冗长且容易出错。而使用 Java 实体转换的 工具类 就可以简化这个过程,并提高代码的可读性和可维护性。 一个常用的 Java 实体转换 工具类 是Apache Commons BeanUtils。它提供了一系列 工具 方法来实现不同实体类之间的复制 属性 获取 属性 值等操作。我们可以通过该 工具类 实现从源实体对象向目标实体对象的 属性 赋值,无需手动编写大量的赋值代码,提高了 开发 效率。 除了BeanUtils,还有其他一些类似的 Java 实体转换 工具类 ,比如Spring Framework中的BeanUtils,Spring Boot中的ModelMapper等,它们都提供了简单易用的方法来进行实体转换操作。 总之, Java 实体转换的 工具类 能够帮助我们简化实体类之间的转换操作,减少冗余代码,提高代码的可读性和可维护性。在实际 开发 中,选择一个合适的 工具类 来进行实体转换是非常重要的。