zoukankan      html  css  js  c++  java
  • Java8通过Function获取字段名(获取实体类的字段名称)

     

    看似很鸡肋其实在某些特殊场景还是比较有用的。
    比如你将实体类转Map或者拿到一个Map结果的时候,你是怎么获取某个map的key和value。

    方法一:
    声明 String key1="aaa"; key为 key1,value 为map.get(key1);
    1         Map<String,Object> map=new HashMap<>();
    2         map.put("aaa",1);
    3 
    4         //获取map的key 和value
    5         //key 为key1
    6         String key1="aaa";
    7         //value 为 map.get(key1)
    8         map.get(key1);


    然后好像日常使用中也没有其他的方法了,下面将带来另外一种使用方法,话不多说直接上代码
      1 import java.io.Serializable;
      2 import java.lang.annotation.ElementType;
      3 import java.lang.annotation.Retention;
      4 import java.lang.annotation.RetentionPolicy;
      5 import java.lang.annotation.Target;
      6 import java.lang.invoke.SerializedLambda;
      7 import java.lang.reflect.Field;
      8 import java.lang.reflect.InvocationTargetException;
      9 import java.lang.reflect.Method;
     10 import java.util.function.Function;
     11 
     12 /**
     13  * Java8通过Function函数获取字段名称(获取实体类的字段名称)
     14  * @see ColumnUtil#main(java.lang.String[]) 使用示例
     15  * @author jx
     16  */
     17 public class ColumnUtil {
     18 
     19     /**
     20      * 使Function获取序列化能力
     21      */
     22     @FunctionalInterface
     23     public interface SFunction<T, R> extends Function<T, R>, Serializable {
     24     }
     25 
     26     /**
     27      * 字段名注解,声明表字段
     28      */
     29     @Target(ElementType.FIELD)
     30     @Retention(RetentionPolicy.RUNTIME)
     31     public @interface TableField {
     32         String value() default "";
     33     }
     34 
     35     //默认配置
     36     static String defaultSplit = "";
     37     static Integer defaultToType = 0;
     38 
     39     /**
     40      * 获取实体类的字段名称(实体声明的字段名称)
     41      */
     42     public static <T> String getFieldName(SFunction<T, ?> fn) {
     43         return getFieldName(fn, defaultSplit);
     44     }
     45 
     46     /**
     47      * 获取实体类的字段名称
     48      * @param split 分隔符,多个字母自定义分隔符
     49      */
     50     public static <T> String getFieldName(SFunction<T, ?> fn, String split) {
     51         return getFieldName(fn, split, defaultToType);
     52     }
     53 
     54     /**
     55      * 获取实体类的字段名称
     56      * @param split 分隔符,多个字母自定义分隔符
     57      * @param toType 转换方式,多个字母以大小写方式返回 0.不做转换 1.大写 2.小写
     58      */
     59     public static <T> String getFieldName(SFunction<T, ?> fn, String split, Integer toType) {
     60         SerializedLambda serializedLambda = getSerializedLambda(fn);
     61 
     62         // 从lambda信息取出method、field、class等
     63         String fieldName = serializedLambda.getImplMethodName().substring("get".length());
     64         fieldName = fieldName.replaceFirst(fieldName.charAt(0) + "", (fieldName.charAt(0) + "").toLowerCase());
     65         Field field;
     66         try {
     67             field = Class.forName(serializedLambda.getImplClass().replace("/", ".")).getDeclaredField(fieldName);
     68         } catch (ClassNotFoundException | NoSuchFieldException e) {
     69             throw new RuntimeException(e);
     70         }
     71 
     72         // 从field取出字段名,可以根据实际情况调整
     73         TableField tableField = field.getAnnotation(TableField.class);
     74         if (tableField != null && tableField.value().length() > 0) {
     75             return tableField.value();
     76         } else {
     77 
     78             //0.不做转换 1.大写 2.小写
     79             switch (toType) {
     80                 case 1:
     81                     return fieldName.replaceAll("[A-Z]", split + "$0").toUpperCase();
     82                 case 2:
     83                     return fieldName.replaceAll("[A-Z]", split + "$0").toLowerCase();
     84                 default:
     85                     return fieldName.replaceAll("[A-Z]", split + "$0");
     86             }
     87 
     88         }
     89 
     90     }
     91 
     92     private static <T> SerializedLambda getSerializedLambda(SFunction<T, ?> fn) {
     93         // 从function取出序列化方法
     94         Method writeReplaceMethod;
     95         try {
     96             writeReplaceMethod = fn.getClass().getDeclaredMethod("writeReplace");
     97         } catch (NoSuchMethodException e) {
     98             throw new RuntimeException(e);
     99         }
    100 
    101         // 从序列化方法取出序列化的lambda信息
    102         boolean isAccessible = writeReplaceMethod.isAccessible();
    103         writeReplaceMethod.setAccessible(true);
    104         SerializedLambda serializedLambda;
    105         try {
    106             serializedLambda = (SerializedLambda) writeReplaceMethod.invoke(fn);
    107         } catch (IllegalAccessException | InvocationTargetException e) {
    108             throw new RuntimeException(e);
    109         }
    110         writeReplaceMethod.setAccessible(isAccessible);
    111         return serializedLambda;
    112     }
    113 
    114 
    115     /**
    116      * 测试用户实体类
    117      */
    118     public static class TestUserDemo implements Serializable {
    119 
    120         private static final long serialVersionUID = 1L;
    121 
    122         private String loginName;
    123         private String name;
    124         private String companySimpleName;
    125 
    126         @ColumnUtil.TableField("nick")
    127         private String nickName;
    128 
    129         public String getLoginName() {
    130             return loginName;
    131         }
    132 
    133         public void setLoginName(String loginName) {
    134             this.loginName = loginName;
    135         }
    136 
    137         public String getNickName() {
    138             return nickName;
    139         }
    140 
    141         public void setNickName(String nickName) {
    142             this.nickName = nickName;
    143         }
    144 
    145         public static long getSerialVersionUID() {
    146             return serialVersionUID;
    147         }
    148 
    149         public String getName() {
    150             return name;
    151         }
    152 
    153         public void setName(String name) {
    154             this.name = name;
    155         }
    156 
    157         public String getCompanySimpleName() {
    158             return companySimpleName;
    159         }
    160 
    161         public void setCompanySimpleName(String companySimpleName) {
    162             this.companySimpleName = companySimpleName;
    163         }
    164     }
    165 
    166 
    167     /**
    168      * 参考示例
    169      */
    170     public static void main(String[] args) {
    171 
    172         //实体类原字段名称返回
    173         System.out.println();
    174         System.out.println("实体类原字段名称返回");
    175         System.out.println("字段名:" + ColumnUtil.getFieldName(TestUserDemo::getLoginName));
    176         System.out.println("字段名:" + ColumnUtil.getFieldName(TestUserDemo::getNickName));
    177         System.out.println("字段名:" + ColumnUtil.getFieldName(TestUserDemo::getCompanySimpleName));
    178 
    179         System.out.println();
    180         System.out.println("实体类字段名称增加分隔符");
    181         System.out.println("字段名:" + ColumnUtil.getFieldName(TestUserDemo::getCompanySimpleName, "_"));
    182 
    183         System.out.println();
    184         System.out.println("实体类字段名称增加分隔符 + 大小写");
    185         System.out.println("字段名:" + ColumnUtil.getFieldName(TestUserDemo::getCompanySimpleName, "_", 0));
    186         System.out.println("字段名:" + ColumnUtil.getFieldName(TestUserDemo::getCompanySimpleName, "_", 1));
    187         System.out.println("字段名:" + ColumnUtil.getFieldName(TestUserDemo::getCompanySimpleName, "_", 2));
    188 
    189 
    190     }
    191 
    192 
    193 }

    输出结果:

  • 相关阅读:
    geth搭建以太坊私链及常用操作
    什么是区块链?
    linux的命令
    MySQL的sql优化
    如何防止秒杀抢购超卖?
    try catch影响Spring事务吗?
    mysql中InnoDB与MyISAM的区别
    进程和线程的区别
    Nginx采用yum安装方式及安装后的目录
    Springboot2.0中jpa默认创建的mysql表为myisam引擎问题
  • 原文地址:https://www.cnblogs.com/IT-study/p/15351980.html
Copyright © 2011-2022 走看看