将Map中的属性赋值给指定类型信息的类并返回对象

package map;

import org.apache.commons.lang3.builder.ReflectionToStringBuilder;

import java.util.HashMap;
import java.util.Map;

/**
 * @Auther: lyf
 * @Date: 2019-08-09 17:50
 * @Description: User user=new User();
 * 之前一直区分不出getField()和getDeclareFiled()这两种的具体用法,只知道getDeclareFiled()方法是拿到
 * User类型中的所有属性(不包含父类的任何属性),却不知道getField()拿出来的是什么东西,但经过调试之后,我总结
 * 出了用法.
 * getDeclareFiled()获取的是User类型里面的所有属性
 * getField()获取到的是User及其父类的所有public属性
 * 相信getMethod()和getDeclareMethod()也是上面的这个意思
 * 具体的还需大家一起验证指正
 * <p>
 * 下面介绍三种检验类型信息的方法
 * 1.instanceof关键字
 * User user=new User();
 * System.out.println(user instanceof User);//user对象是不是就是User类型,或者说user对象是不是就是User扩展类的实现类
 * a instanceof B 其中a是对象,B是类名.这个表达式的意思就是:'a对象对应的类型是A,只要A==B或者是A基础与B,那么就返回true'
 * 2.使用类型信息class
 * BaseClass base=new BaseClass();
 * User user=new User();//这里假设User继承了BaseClass
 * System.out.println(user.getClass!=base.getClass())//输出true,因为两者的类型信息是不一样的
 * System.out.println(user instanceof BaseClass);//输出true,因为user是BaseClass扩展类的实现类
 * 这种情况,只有当两者的类型都是同一个的时候才返回true.子类的类型信息!=父类的类型信息
 * 3.使用isInstance()方法
 * User user=new User();
 * Class<User> clazz=user.getClass();//获取User类的类型信息
 * System.out.println(clazz.isInstance(user));//动态的判断user对象的类型信息是不是就是clazz
 */
public class MapTest {

    public static void main(String[] args) {
        Map<String, Object> map = new HashMap<>(1);
        map.put("arr", new Integer[]{1, 2, 3, 4, 5, 6, 7});
        map.put("intArr", new int[]{1, 2, 3, 4, 5, 6, 7});
        map.put("age", 22);
        User user = MapUtils.mapToObject(map, User.class);
        System.out.println(ReflectionToStringBuilder.toString(user));
    }
}

class User extends BaseClass {

    private Integer[] arr;

    private int age;

    public Integer[] getArr() {
        return arr;
    }

    public void setArr(Integer[] arr) {
        this.arr = arr;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

class BaseClass {

    private int[] intArr;

    public int[] getIntArr() {
        return intArr;
    }

    public void setIntArr(int[] intArr) {
        this.intArr = intArr;
    }
}

 

 

package map;

import java.lang.reflect.Field;
import java.util.Map;

/**
 * @Auther: lyf
 * @Date: 2019-08-09 17:38
 * @Description:
 */
public abstract class MapUtils {

    /**
     * 将Map装换成类型T的对象
     * 前端传JSON格式的时候,可以先使用Map来接收参数,然后再使用这个方法来进行参数值的获取,以提高接收JSON格式时的接口扩展性
     * 意思是:controller的方法里一般都是使用类来接收参数,当使用@RequestBody注解后,该接口只能接收类里面所包含的属性
     * 如果存在其他属性的话就会找不到这个接口(就会出现404,使用了@RequestParam注解估计效果也会是404,大家可以试一下),
     * 所以为了提高接口的扩展性的话,就得先用Map接收参数,
     * 然后再从Map中获取参数值赋值给表单
     *
     * @param model
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T mapToObject(Map<String, Object> model, Class<T> clazz) {
        T t = null;
        try {
            t = clazz.newInstance();
            //getFields()获取到所有public属性,包含基类和扩展类
            //clazz.getDeclaredFields()获取到扩展类的所有属性,包含private属性
            Field[] fields = clazz.getDeclaredFields();
            if (fields != null && fields.length > 0) {
                //遍历所有属性
                for (Field field : fields) {
                    //通过属性的名称去Map中取数据
                    Object fieldValue = model.get(field.getName());
                    if (fieldValue != null) {
                        //如果数据存在的话,就判断数据类型是否一致,一致就将值设置到t对象中
                        //从而实现赋值操作
                        if (field.getType() == fieldValue.getClass()) {
                            //这里除了8大基本数据类型外的其他类型形式都支持
                            //只要类型一致就能进行操作,想满足其他情况需要自己做兼容操作
                            field.setAccessible(true);
                            field.set(t, fieldValue);
                        }
                    }
                }
            }
        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
        return t;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值