暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Lambda实现通过getter/setter方法引用拿到属性名与方法名

风雪留客 2021-08-26
949

前言

在开发过程中,很多开发场景需要用到Java Bean的属性名,但是直接采用字符串写死属性名的形式容易产生问题,属性名一旦变化,我们可能会忘记修改对应的属性名,且编译器不会告诉你你的字符串需要同步修改。不过,JDK8的Lambda可以通过方法引用简化代码,同样也可以通过getter/setter的方法引用拿到属性名,从而避免潜在的bug。

实现步骤

Get方式

编写函数式接口
  1. @FunctionalInterface

  2. public interface IGetter<T> extends Serializable {

  3. Object apply(T source);

  4. }

编写工具类
  1. @Slf4j

  2. public class EntityUtil {

  3. /**

  4. * 缓存类-Lambda的映射关系

  5. */

  6. private static Map<Class, SerializedLambda> CLASS_LAMDBA_CACHE = new ConcurrentHashMap<>();


  7. /***

  8. * 转换方法引用为属性名

  9. * @param fn

  10. * @return

  11. */

  12. public static <T> String convertToFieldName(IGetter<T> fn) {

  13. SerializedLambda lambda = getSerializedLambda(fn);

  14. String methodName = lambda.getImplMethodName();

  15. String prefix = null;

  16. if (methodName.startsWith("get")) {

  17. prefix = "get";

  18. } else if (methodName.startsWith("is")) {

  19. prefix = "is";

  20. }

  21. if (prefix == null) {

  22. log.warn("无效的getter方法: " + methodName);

  23. }

  24. // 截取get/is之后的字符串并转换首字母为小写,自己实现对应的功能

  25. return StrUtil.lowerFirst(StrUtil.removeAll(methodName, prefix));

  26. }


  27. // 获取方法名

  28. public static <T> String getMethodName(IGetter<T> fn) {

  29. SerializedLambda lambda = getSerializedLambda(fn);

  30. // 获取方法名

  31. return lambda.getImplMethodName();

  32. }


  33. /***

  34. * 获取类对应的Lambda

  35. * @param fn

  36. * @return

  37. */

  38. private static SerializedLambda getSerializedLambda(Serializable fn) {

  39. //先检查缓存中是否已存在

  40. SerializedLambda lambda = CLASS_LAMDBA_CACHE.get(fn.getClass());

  41. if (lambda == null) {

  42. try {

  43. //提取SerializedLambda并缓存

  44. Method method = fn.getClass().getDeclaredMethod("writeReplace");

  45. method.setAccessible(Boolean.TRUE);

  46. lambda = (SerializedLambda) method.invoke(fn);

  47. CLASS_LAMDBA_CACHE.put(fn.getClass(), lambda);

  48. } catch (Exception e) {

  49. log.error("获取SerializedLambda异常, class=" + fn.getClass().getSimpleName(), e);

  50. }

  51. }

  52. return lambda;

  53. }


  54. }

使用方式
  1. System.out.println(EntityUtil.convertToFieldName(LayerQueryForm::getCityCode));

  2. System.out.println(EntityUtil.getMethodName(LayerQueryForm::getCityCode));

输出结果
  1. cityCode

  2. getCityCode

Set方式

原理类似,故省略....


文章转载自风雪留客,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论