• Java8通过Function获取字段名


    摘要:Java8通过Function获取字段名。不用再硬编码,效果类似于mybatis-plus的LambdaQueryWrapper。

    本文总共三个步骤:
    1、使Function获取序列化能力;
    2、通过SFunction获取字段名;
    3、建一些业务代码进行测试;

    使Function获取序列化能力

    import java.io.Serializable;
    import java.util.function.Function;
    
    /**
     * 使Function获取序列化能力
     */
    @FunctionalInterface
    public interface SFunction<T, R> extends Function<T, R>, Serializable {
    }
    

    通过SFunction获取字段名

    import java.lang.invoke.SerializedLambda;
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    public class ColumnUtil {
    
        public static <T> String getName(SFunction<T, ?> fn) {
            // 从function取出序列化方法
            Method writeReplaceMethod;
            try {
                writeReplaceMethod = fn.getClass().getDeclaredMethod("writeReplace");
            } catch (NoSuchMethodException e) {
                throw new RuntimeException(e);
            }
    
            // 从序列化方法取出序列化的lambda信息
            boolean isAccessible = writeReplaceMethod.isAccessible();
            writeReplaceMethod.setAccessible(true);
            SerializedLambda serializedLambda;
            try {
                serializedLambda = (SerializedLambda) writeReplaceMethod.invoke(fn);
            } catch (IllegalAccessException | InvocationTargetException e) {
                throw new RuntimeException(e);
            }
            writeReplaceMethod.setAccessible(isAccessible);
    
            // 从lambda信息取出method、field、class等
            String fieldName = serializedLambda.getImplMethodName().substring("get".length());
            fieldName = fieldName.replaceFirst(fieldName.charAt(0) + "", (fieldName.charAt(0) + "").toLowerCase());
            Field field;
            try {
                field = Class.forName(serializedLambda.getImplClass().replace("/", ".")).getDeclaredField(fieldName);
            } catch (ClassNotFoundException | NoSuchFieldException e) {
                throw new RuntimeException(e);
            }
    
            // 从field取出字段名,可以根据实际情况调整
            TableField tableField = field.getAnnotation(TableField.class);
            if (tableField != null && tableField.value().length() > 0) {
                return tableField.value();
            } else {
                return fieldName.replaceAll("[A-Z]", "_$0").toLowerCase();
            }
        }
    }
    

    建一些业务代码进行测试

    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    /**
     * 字段名注解。测试用
     */
    @Target(ElementType.FIELD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface TableField {
        String value() default "";
    }
    
    import java.io.Serializable;
    
    /**
     * 用户实体类。测试用
     */
    public class User implements Serializable {
    
        private String loginName;
    
        @TableField("nick")
        private String nickName;
    
        public String getLoginName() {
            return loginName;
        }
    
        public void setLoginName(String loginName) {
            this.loginName = loginName;
        }
    
        public String getNickName() {
            return nickName;
        }
    
        public void setNickName(String nickName) {
            this.nickName = nickName;
        }
    }
    
    /**
     * 测试用
     */
    public class Test {
        public static void main(String[] args) {
            System.out.println("字段名:" + ColumnUtil.getName(User::getLoginName));
            System.out.println("字段名:" + ColumnUtil.getName(User::getNickName));
        }
    }
    

    运行结果:
    字段名:login_name
    字段名:nick

  • 相关阅读:
    <11>改变图像的尺寸,方便上传服务器
    <10>获取当前时间
    <09>获得字符串的size
    <08>时间戳的转换
    <07>手机号码验证
    <06>邮箱的验证
    <05>判断字符串是否为空
    WKWebView的一些知识
    objc_setAssociatedObject 使用
    linker command failed with exit code 1 (use -v to see invocation) 编译报错原因
  • 原文地址:https://www.cnblogs.com/liangweiping/p/12792418.html
Copyright © 2020-2023  润新知