java lambda获取方法名称与属性名称

背景

有时候我们需要将属性名称作为方法参数进行传递,常见的方式就是定义一个string类型的形参,调用方法的时候传递实参名称,例如:

static String columnToDate(@Nonnull String column) {
	return String.format("to_char(%s, 'yyyyMMdd')", column);
}

调用:

String str = CommonConstants.columnToDate("post_date");

上述方式最大的弊端就是将字段名写死在代码中,如果要修改字段名,则需要全局修改,为了便于维护,我们往往会将post_date定义为常量,调用方法时传递常量,这样修改字段名称的时候只需要修改常量值即可。
在java8之后我们可以通过lambda的方法引用来获取属性名,这样连定义常量的步骤都省了,mybatis-plus就是采用这种方式。

实现

  1. 定义支持序列化的Function
/**
 * 支持序列化的 Function
 */
@FunctionalInterface
public interface SFunction<T, R> extends Function<T, R>, Serializable {
}
  1. 通过调用lambda表达式看不见的writeReplace方法获取返回值SerializedLambda继而获取到方法名称
import java.lang.invoke.SerializedLambda;
import java.lang.reflect.Method;
    /**
     * @description: 获取属性名称
     * @date 15:49 2024/10/8
     * @param column 字段方法引用
     * @return 属性名称
     **/
    @SneakyThrows
    public static <R> String findFieldName(SFunction<R, ?> column) {
        Method method = column.getClass().getDeclaredMethod("writeReplace");
        method.setAccessible(true);
        SerializedLambda serializedLambda = (SerializedLambda) method.invoke(column);
        String methodName = serializedLambda.getImplMethodName();
        return methodToProperty(methodName);
    }

    /**
     * @description: 从方法名获取属性名
     * @date 15:48 2024/10/8
     * @param methodName 方法名称
     * @return 属性名称
     **/
    private static String methodToProperty(String methodName) {
        if (methodName == null || methodName.isEmpty()) {
            return "";
        }
        String name;
        if (methodName.startsWith("is")) {
            name = methodName.substring(2);
        } else if (methodName.startsWith("get") || methodName.startsWith("set")) {
            name = methodName.substring(3);
        } else {
            throw new RuntimeException("Error parsing property name '" + methodName + "'.  Didn't start with getter/setter prefix!");
        }
        //首字母小写
        if (name.length() == 1 || name.length() > 1 && Character.isLowerCase(name.charAt(1))) {
            name = name.substring(0, 1).toLowerCase() + name.substring(1);
        }
        return name;
    }
  1. 测试
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值