通过反射遍历实体类的属性和值,以及所有方法

1、前提

由于业务要求,通过openfeign调用别人的http接口后,返回的值是一个jsonObject和jsonArray的组合格式比较复杂,那么它的字段与实体的字段名字是不对应,只需获取到它的value的key的值到各个字段里,那么问题来了,这个值是属于哪个字段的值呢,好在这些值的顺序就是字段顺序,那么我只需要通过反射遍历实体类的属性的set方法去赋值即可

2、热身(这个类主要给你学学怎么用反射去获取实体类的属性、值和方法)

package com.zhaohy.app.utils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;

import com.zhaohy.app.entity.User;
/**
 * 反射工具类
 * @author zhaohy
 *
 */
public class ReflectUtil {
    
    
    /**
     * 根据属性,获取get方法
    *
    * @param ob   对象
    * @param name 属性名
    * @return
    * @throws Exception
    */
   public static Object getGetMethod(Object ob, String name) throws Exception {
    
    
       Method[] m = ob.getClass().getMethods();
       for (int i = 0; i < m.length; i++) {
    
    
           if (("get" + name).toLowerCase().equals(m[i].getName().toLowerCase())) {
    
    
               return m[i].invoke(ob);
           }
       }
       return null;
   }

   /**
    * 根据属性,拿到set方法,并把值set到对象中
    *
    * @param obj       对象
    * @param clazz     对象的class
    * @param typeClass
    * @param value
    *     示例:    DataReq req=new DataReq();
    *         String field2 = "start";  属性名
    *         ReflectUtil.setValue(req,DataReq.class,field2,DataReq.class.getDeclaredField(field2).getType(),"汪汪");
    *
    *
    */
   public static void setValue(Object obj, Class<?> clazz, String filedName, Class<?> typeClass, Object value) {
    
    
       filedName = removeLine(filedName);
       String methodName = "set" + filedName.substring(0, 1).toUpperCase() + filedName.substring(1);
       try {
    
    
           Method method = clazz.getDeclaredMethod(methodName, new Class[] {
    
     typeClass });
           method.invoke(obj, new Object[] {
    
     getClassTypeValue(typeClass, value) });
       } catch (Exception ex) {
    
    
           ex.printStackTrace();
       }
   }

   /**
    * 通过class类型获取获取对应类型的值
    *
    * @param typeClass class类型
    * @param value     值
    * @return Object
    */
   private static Object getClassTypeValue(Class<?> typeClass, Object value) {
    
    
       if (typeClass == int.class || value instanceof Integer) {
    
    
           if (null == value) {
    
    
               return 0;
           }
           return value;
       } else if (typeClass == short.class) {
    
    
           if (null == value) {
    
    
               return 0;
           }
           return value;
       } else if (typeClass == byte.class) {
    
    
           if (null == value) {
    
    
               return 0;
           }
           return value;
       } else if (typeClass == double.class) {
    
    
           if (null == value) {
    
    
               return 0;
           }
           return value;
       } else if (typeClass == long.class) {
    
    
           if (null == value) {
    
    
               return 0;
           }
           return value;
       } else if (typeClass == String.class) {
    
    
           if (null == value) {
    
    
               return "";
           }
           return value;
       } else if (typeClass == boolean.class) {
    
    
           if (null == value) {
    
    
               return true;
           }
           return value;
       } else if (typeClass == BigDecimal.class) {
    
    
           if (null == value) {
    
    
               return new BigDecimal(0);
           }
           return new BigDecimal(value + "");
       } else {
    
    
           return typeClass.cast(value);
       }
   }
   /**
    * 处理字符串 如: abc_dex ---> abcDex
    *
    * @param str
    * @return
    */
   public static String removeLine(String str) {
    
    
       if (null != str && str.contains("_")) {
    
    
           int i = str.indexOf("_");
           char ch = str.charAt(i + 1);
           char newCh = (ch + "").substring(0, 1).toUpperCase().toCharArray()[0];
           String newStr = str.replace(str.charAt(i + 1), newCh);
           String newStr2 = newStr.replace("_", "");
           return newStr2;
       }
       return str;
   }
   
    public static void main(String[] args) {
    
    
        User user = new User();
        user.setUserId(1);
        user.setUserName("zhaohy");
        user.setSex(1);
        user.setJob("programmer");
        user.setEmail("[email protected]");
        
        System.out.println("通过反射遍历实体类属性,和值");
        //通过反射遍历实体类属性,和值
        Field[] fields = User.class.getDeclaredFields();
        for(Field field: fields) {
    
    
            //反射时让私有变量变成可访问
            field.setAccessible(true);
            try {
    
    
                System.out.println("实体类的属性名称:" + field.getName() + " 类型:" + field.getType() + " 属性的值:" + field.get(user));
            } catch (Exception e) {
    
    
                e.printStackTrace();
            }
        }
        
        System.out.println("遍历实体类的方法名");
        //遍历实体类的方法名
        Method[] methods = User.class.getMethods();
        for(Method method:methods) {
    
    
            System.out.println("实体类的方法名:" + method.getName());
        }
        
        System.out.println("获取值方法二:通过拼接get方法来获取值打印get方法的值,注意如果是boolean类型需要做特殊处理");
        //获取值方法二:通过拼接get方法来获取值打印get方法的值,注意如果是boolean类型需要做特殊处理
        for(Field field: fields) {
    
    
            try {
    
    
                System.out.println("实体类的属性名称:" + field.getName() + " 类型:" + field.getType() + " 属性的值:" + getGetMethod(user, field.getName()));
            } catch (Exception e) {
    
    
                e.printStackTrace();
            }
        }
        
        System.out.println("通过反射来给属性赋值方法一");
        //通过反射来给属性赋值方法一
        for(Field field: fields) {
    
    
            //反射时让私有变量变成可访问
            field.setAccessible(true);
            try {
    
    
                if(field.getName().equals("userName")) {
    
    
                    field.set(user, "zhaohyTest");
                }
                System.out.println("实体类的属性名称:" + field.getName() + " 类型:" + field.getType() + " 属性的值:" + field.get(user));
            } catch (Exception e) {
    
    
                e.printStackTrace();
            }
        }
        
        System.out.println("通过反射来给属性赋值方法二,拼接setget方法的方式,注意如果是boolean类型需要做特殊处理");
        //通过反射来给属性赋值方法二,拼接setget方法的方式,注意如果是boolean类型需要做特殊处理
        for(Field field: fields) {
    
    
            try {
    
    
                if(field.getName().equals("userName")) {
    
    
                    setValue(user, User.class, field.getName(), field.getType(), "zhaohyTest2");
                }
                System.out.println("实体类的属性名称:" + field.getName() + " 类型:" + field.getType() + " 属性的值:" + getGetMethod(user, field.getName()));
            } catch (Exception e) {
    
    
                e.printStackTrace();
            }
        }
        
    }

}

通过反射遍历实体类属性,和值
实体类的属性名称:userId 类型:class java.lang.Integer 属性的值:1
实体类的属性名称:userName 类型:class java.lang.String 属性的值:zhaohy
实体类的属性名称:sex 类型:class java.lang.Integer 属性的值:1
实体类的属性名称:job 类型:class java.lang.String 属性的值:programmer
实体类的属性名称:email 类型:class java.lang.String 属性的值:[email protected]
遍历实体类的方法名
实体类的方法名:getUserId
实体类的方法名:getUserName
实体类的方法名:getSex
实体类的方法名:getJob
实体类的方法名:getEmail
实体类的方法名:setUserId
实体类的方法名:setUserName
实体类的方法名:setSex
实体类的方法名:setJob
实体类的方法名:setEmail
实体类的方法名:wait
实体类的方法名:wait
实体类的方法名:wait
实体类的方法名:equals
实体类的方法名:toString
实体类的方法名:hashCode
实体类的方法名:getClass
实体类的方法名:notify
实体类的方法名:notifyAll
获取值方法二:通过拼接get方法来获取值打印get方法的值,注意如果是boolean类型需要做特殊处理
实体类的属性名称:userId 类型:class java.lang.Integer 属性的值:1
实体类的属性名称:userName 类型:class java.lang.String 属性的值:zhaohy
实体类的属性名称:sex 类型:class java.lang.Integer 属性的值:1
实体类的属性名称:job 类型:class java.lang.String 属性的值:programmer
实体类的属性名称:email 类型:class java.lang.String 属性的值:[email protected]
通过反射来给属性赋值方法一
实体类的属性名称:userId 类型:class java.lang.Integer 属性的值:1
实体类的属性名称:userName 类型:class java.lang.String 属性的值:zhaohyTest
实体类的属性名称:sex 类型:class java.lang.Integer 属性的值:1
实体类的属性名称:job 类型:class java.lang.String 属性的值:programmer
实体类的属性名称:email 类型:class java.lang.String 属性的值:[email protected]
通过反射来给属性赋值方法二,拼接setget方法的方式,注意如果是boolean类型需要做特殊处理
实体类的属性名称:userId 类型:class java.lang.Integer 属性的值:1
实体类的属性名称:userName 类型:class java.lang.String 属性的值:zhaohyTest2
实体类的属性名称:sex 类型:class java.lang.Integer 属性的值:1
实体类的属性名称:job 类型:class java.lang.String 属性的值:programmer
实体类的属性名称:email 类型:class java.lang.String 属性的值:[email protected]
//所有get方法和set方法
public void getMethod(Object obj){
    
    
    Class<...> clazz=obj.getClass();//获得实体类名
    Field[] fields = obj.getDeclaredFields();//获得属性
    //获得Object对象中的所有方法
    for(Field field:fields){
    
    
        PropertyDescriptor pd = new PropertyDescriptor(field.getName(), clazz);
        Method getMethod = pd.getReadMethod();//获得get方法
        //getMethod.invoke(obj);//此处为执行该Object对象的get方法
        Method setMethod = pd.getWriteMethod();//获得set方法    
        //setMethod.invoke(obj,"参数");//此处为执行该Object对象的set方法
    }
}

//读取某个类下所有变量的名称
public void getMethod(Class clz) {
    
    
	// 获取f对象对应类中的所有属性域
	Field[] fields = clz.getDeclaredFields();
	for (int i = 0, len = fields.length; i < len; i++) {
    
    
		// 对于每个属性,获取属性名
		String varName = fields[i].getName();
		System.out.println("变量名称为:"+varName);
	}
}
    @SneakyThrows
    public static void main(String[] args)  {
    
    
        Class<PvTelemeterStatus> pv = PvTelemeterStatus.class;
        Field[] fields = pv.getDeclaredFields();
//        System.out.println(fields.length);
        PvTelemeterStatus p  = new PvTelemeterStatus();
        for (int i=0 ; i<fields.length ; i++){
    
    
            System.out.println(fields[i].getName());
            PropertyDescriptor pd = new PropertyDescriptor(fields[i].getName(), pv);
            Method readMethod = pd.getReadMethod();
            Method writeMethod = pd.getWriteMethod();

            Class<?> type = fields[i].getType();
          	if(type == Float.class){
    
    
                writeMethod.invoke(p,5.23f);//此处为执行该Object对象的set方法
            }else if (type == Integer.class){
    
    
                writeMethod.invoke(p,1);//此处为执行该Object对象的set方法
            }else {
    
    
                writeMethod.invoke(p,"11");//此处为执行该Object对象的set方法
            }
        }
        System.out.println(p);
    }

3、我的用法

获取class -> 获取Field[] -> PropertyDescriptor传入字段名和class -> pd.getWriteMethod()获取写入方法 -> writeMethod.invoke触发写入方法


            Class<PvTelemeterStatus> telemeterClass = PvTelemeterStatus.class;
            Field[] telemeterFields = telemeterClass.getDeclaredFields();
            PvTelemeterStatus pvTelemeterStatus  = new PvTelemeterStatus();
            pvTelemeterStatus.setDeviceId((String) guid);


            for (int j =0 ; j < telemeterFields.length - 3 ; j++){
    
    
                PropertyDescriptor pd = new PropertyDescriptor(telemeterFields[j+3].getName(), telemeterClass);
                Method writeMethod = pd.getWriteMethod();
                Class<?> type = telemeterFields[j+3].getType();
                Object value = points.getJSONObject(j).get("value");
                Object timestamp = points.getJSONObject(j).get("timestamp");

                if ("invStatus".equals(telemeterFields[j+3].getName())){
    
    
                    LocalDateTime localDateTime = LocalDateTime.ofEpochSecond(Long.valueOf(timestamp.toString()), 0, ZoneOffset.ofHours(8));
                    pvTelemeterStatus.setAcquisitionTime(localDateTime);
                    writeMethod.invoke(pvTelemeterStatus, ReflectUtil.getClassTypeValue(type,value));//此处为执行该Object对象的set方法
                }else{
    
    
                    writeMethod.invoke(pvTelemeterStatus, ReflectUtil.getClassTypeValue(type,value));//此处为执行该Object对象的set方法
                }
            }
            pvTelemeterService.save(pvTelemeterStatus);
    /**
     * 通过class类型获取获取对应类型的值
     *
     * @param typeClass class类型
     * @param value     值
     * @return Object
     */
    public static Object getClassTypeValue(Class<?> typeClass, Object value) {
    
    
        if (typeClass == Integer.class || value instanceof Integer) {
    
    
            if (null == value) {
    
    
                return 0;
            }
            return Integer.valueOf((String) value);
        } else if (typeClass == Short.class) {
    
    
            if (null == value) {
    
    
                return 0;
            }
            return Short.parseShort((String) value);
        } else if (typeClass == Double.class) {
    
    
            if (null == value) {
    
    
                return 0;
            }
            return Double.parseDouble((String) value);
        } else if (typeClass == Float.class) {
    
    
            if (null == value) {
    
    
                return 0;
            }
            return Float.parseFloat((String) value);
        } else if (typeClass == Long.class) {
    
    
            if (null == value) {
    
    
                return 0;
            }
            return Long.parseLong((String) value);
        } else if (typeClass == String.class) {
    
    
            if (null == value) {
    
    
                return "";
            }
            return String.valueOf(value);
        } else if (typeClass == Boolean.class) {
    
    
            if (null == value) {
    
    
                return true;
            }
            return Boolean.parseBoolean((String) value);
        } else if (typeClass == BigDecimal.class) {
    
    
            if (null == value) {
    
    
                return new BigDecimal(0);
            }
            return new BigDecimal(value + "");
        } else {
    
    
            return typeClass.cast(value);
        }
    }

这里说下为什么要telemeterFields[j+3].getName() ,因为这个类的前三个字段返回的数据没有这个三个字段的值,所以把他们跳过

猜你喜欢

转载自blog.csdn.net/weixin_42835230/article/details/128413764