通过方法引用获取方法名

导读:本篇文章讲解 通过方法引用获取方法名,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

在学习Mybatis-plus时,可以通过getter方法的方法引用来获取到对应的字段名

LambdaQueryWrapper<PurchaseOrder> wrapper = new LambdaQueryWrapper<>();
wrapper.like(PurchaseOrder::getBillTypeName, order.getBillTypeName());

这种情况避免了魔法值的出现,也不需要手动写死,避免因需求改变而导致的错误

QueryWrapper<OrderDataDTO> wrapper = new QueryWrapper<>();
wrapper.like("bill_type_name", dto.getBillTypeName())

lambda表达式不仅可以通过方法引用简化代码,也可以通过getter/setter的方法引用获取到对应的属性名,避免出现bug

代码实现

函数式接口

首先需要定义一个函数式接口来接受我们的方法引用,该接口必须要继承 Serializable 才能获取到方法信息

@FunctionalInterface
public interface SFunction<T> extends Serializable {
    /**
     * 获取对象属性信息
     *
     * @param source
     * @return
     */
    Object get(T source);
}

函数式接口:如果一个接口中只有一个抽象方法(可以包含多个默认方法或多个static方法),那么该接口就是函数式接口。本质上是将函数的实现直接转换为了一个声明语句的定义,极大简化了原有的实现方式

@FunctionalInterface:用来指定某个接口必须是函数式接口,所以该注解只能修饰接口,加上标注, 则会触发JavaCompiler的检查。对于符合函数接口的接口,加不加都无关紧要,但是加上则会提供一层编译检查的保障。如果不符合,则会报错。

工具类

解析Function获取字段属性名

public class ConvertUtil {

    public static final String GET = "get";

    public static final String IS = "is";

    private static final Map<Class<?>, SerializedLambda> CLASS_LAMBDA_CACHE = new ConcurrentHashMap<>();

    /**
     * 转换方法引用为属性名
     *
     * @param fn
     * @param <T>
     * @return
     */
    public static <T> String convertToFieldName(SFunction<T> fn) {
        SerializedLambda lambda = getSerializedLambda(fn);
        String methodName = lambda.getImplMethodName();
        if (methodName.startsWith(GET)) {
            methodName = methodName.substring(3);
        } else if (methodName.startsWith(IS)) {
            methodName = methodName.substring(2);
        } else {
            throw new IllegalArgumentException("无效的getter方法:" + methodName);
        }
        return StringUtil.firstToLowerCase(methodName);
    }

    public static SerializedLambda getSerializedLambda(Serializable fn) {
        SerializedLambda lambda = CLASS_LAMBDA_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_LAMBDA_CACHE.put(fn.getClass(), lambda);
            } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        }
        return lambda;
    }
}
/**
 * 首字母转换小写
 *
 * @param str 需要转换的字符串
 * @return 转换好的字符串
 */
public static String firstToLowerCase(final String str) {
    if (isBlank(str)) {
        return EMPTY;
    }
    return str.substring(0, 1).toLowerCase() + str.substring(1);
}

测试

public static void main(String[] args) {
    String firstNameFieldNameStyle = ConvertUtil.convertToFieldName(User::getFirstName);
    String firstNameUnderlineStyle = ConvertUtil.convertToUnderline(User::getFirstName);
    System.out.println("firstNameFieldNameStyle:" + firstNameFieldNameStyle);
    System.out.println("firstNameUnderlineStyle:" + firstNameUnderlineStyle);
}

通过方法引用获取方法名

 

想要深入研究的可以看这个链接:Lambda表达式获取传入的方法引用的方法名_社恐Coder的博客-CSDN博客

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/95905.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!