反射与简单java类(单值操作和级联操作)

利用反射实现单值和级联操作

单值操作

使用反射快速赋值,不涉及级联(如:ball.name)。

public class TestSimpleJava {
    public static void main(String[] args) {
        BasketBall basketBall = ObjectFactory.getInstance(BasketBall.class, InputData.testInput());
        System.out.println(basketBall);
    }
}

class InputData {

    public static Map<String, String> testInput() {
        Map<String, String> map = new HashMap<>(15);
        map.put("name", "篮球");
        map.put("brand", "乔丹");
        map.put("price", "199");
        map.put("buyCount", "5");
        map.put("produce", "100");
        map.put("testTime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        return map;
    }
}

class ObjectFactory<T> {
    private ObjectFactory() {
    }

    public static <T> T getInstance(Class<?> clazz, Map<String, String> map) {
        Object object = null;
        try {
            object = clazz.getDeclaredConstructor().newInstance();
            BeanUtil.setValue(object, map);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return (T) object;
    }
}

class BeanUtil {
    private BeanUtil() {
    }

    public static void setValue(Object object, Map<String, String> value) {
        Iterator<Map.Entry<String, String>> iterator = value.entrySet().iterator();
        while (iterator.hasNext()) {
            //获取当前数据
            Map.Entry<String, String> entry = iterator.next();
            try {
                //根据传入的key获取属性和类型
                Field field = object.getClass().getDeclaredField(entry.getKey());
                //获取setter方法
                Method methodSet = object.getClass().getDeclaredMethod("set" + StringUtil.toUpperCaseString(entry.getKey()), field.getType());
                //解除封装
                methodSet.setAccessible(true);
                //导入数据
                methodSet.invoke(object, isType(field, entry.getValue()));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private static Object isType(Field field, String value) throws ParseException {
        String fileType = field.getType().getName();
        String simpleDateFormat = null;
        if (String.valueOf(String.class.getName()).equalsIgnoreCase(field.getType().getName())) {
            return value;
        }

        if (String.valueOf(int.class.getName()).equalsIgnoreCase(fileType) || String.valueOf(Integer.class.getName()).equalsIgnoreCase(fileType)) {
            try {
                return Integer.parseInt(value);
            } catch (Exception e) {
                return 0;
            }
        }

        if (String.valueOf(double.class.getName()).equalsIgnoreCase(fileType) || String.valueOf(Double.class.getName()).equalsIgnoreCase(fileType)) {
            try {
                return Double.parseDouble(value);
            } catch (Exception e) {
                return 0.0;
            }
        }

        if (String.valueOf(long.class.getName()).equalsIgnoreCase(fileType) || String.valueOf(Long.class.getName()).equalsIgnoreCase(fileType)) {
            try {
                return Long.parseLong(value);
            } catch (Exception e) {
                return 0;
            }
        }

        if (String.valueOf(Date.class.getName()).equalsIgnoreCase(fileType)) {
            if (value == null || "".equals(value)) {
                return null;
            } else {
                Date date = null;
                String regex = "\\d{4}+-\\d{1,2}+-\\d{1,2}+";
                if (value.matches(regex)) {
                    try {
                        date = new SimpleDateFormat("yyyy-MM-dd").parse(value);
                    } catch (Exception e) {
                        return null;
                    }
                    return date;
                }
                regex = "\\d{4}+-\\d{1,2}+-\\d{1,2}+ \\d{1,2}+:\\d{1,2}+:\\d{1,2}+";
                if (value.matches(regex)) {
                    try {
                        date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(value);
                    } catch (Exception e) {
                        return null;
                    }
                    return date;
                }
            }
        }
        return null;
    }

结果:

BasketBall{name='篮球', brand='乔丹', price=199.0, buyCount=5, produce=100, testTime=Sun Mar 08 23:54:34 CST 2020, ball=null}

级联操作

使用反射快速给关系类赋值(必须先进行实例化操作)。

public class TestSimpleJava {
    public static void main(String[] args) {
        BasketBall basketBall = ObjectFactory.getInstance(BasketBall.class, InputData.testInput());
        System.out.println(basketBall);
        System.out.println(basketBall.getBall().toString());
        System.out.println(basketBall.getBall().getCreateCompany());
    }
}

class InputData {

    public static Map<String, String> testInput() {
        Map<String, String> map = new HashMap<>(15);
        map.put("name", "篮球");
        map.put("brand", "乔丹");
        map.put("price", "199");
        map.put("buyCount", "5");
        map.put("produce", "100");
        map.put("testTime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        map.put("ball.name", "球");
        map.put("ball.createCompany.companyName", "篮球公司");
        return map;
    }
}

class ObjectFactory<T> {
    private ObjectFactory() {
    }

    public static <T> T getInstance(Class<?> clazz, Map<String, String> map) {
        Object object = null;
        try {
            object = clazz.getDeclaredConstructor().newInstance();
            BeanUtil.setValue(object, map);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return (T) object;
    }
}

class BeanUtil {
    private BeanUtil() {
    }

    public static void setValue(Object object, Map<String, String> value) {
        Iterator<Map.Entry<String, String>> iterator = value.entrySet().iterator();
        Object currentObject = null;
        while (iterator.hasNext()) {
            //获取当前数据
            Map.Entry<String, String> entry = iterator.next();
            try {
                String fieldData = null;
                //重置currentObject,每次循环都换成Object(BasketBall)
                currentObject = object;
                //判断是否有带.的数据
                if (entry.getKey().contains(".")) {
                    fieldData = entry.getKey().substring(entry.getKey().lastIndexOf(".") + 1);
                     //根据.进行分割
                    String[] splitType = entry.getKey().split("\\.");
                    //object包含类的数据赋给currentObject
                    currentObject = object;
                    for (int i = 0; i < splitType.length - 1; ++i) {
                        //每次刷新获取类的数据,第一次查询BasketBall类get数据,第二次刷新获取Ball类的get数据
                        Method methodGet = currentObject.getClass().getDeclaredMethod("get" + StringUtil.toUpperCaseString(splitType[i]));
                        //第一次在BasketBall获取getBall()数据,第二次获取Ball类的getCreateCompany()数据
                        Object obj = methodGet.invoke(currentObject);
                        if (obj == null) {
                            //根据currentObject获取splitType[i]数据
                            Field field = currentObject.getClass().getDeclaredField(splitType[i]);
                            //解锁(解除封装)
                            field.setAccessible(true);
                            //根据currentObject的数据更新获取set数据
                            Method methodSet = currentObject.getClass().getDeclaredMethod("set" + StringUtil.toUpperCaseString(splitType[i]), field.getType());
                            //obj是变动的,第一次为Ball实例,第二次为CreateCompany的数据
                            obj = field.getType().getDeclaredConstructor().newInstance();
                            methodSet.invoke(currentObject, obj);
                        }
                        //刷新currentObject的值
                        currentObject = obj;
                    }
                } else {
                    fieldData = entry.getKey();
                }
                //根据传入的key获取属性和类型
                Field field = currentObject.getClass().getDeclaredField(fieldData);
                //获取setter方法
                Method methodSet = currentObject.getClass().getDeclaredMethod("set" + StringUtil.toUpperCaseString(fieldData), field.getType());
                //解除封装
                methodSet.setAccessible(true);
                //导入数据
                methodSet.invoke(currentObject, isType(field, entry.getValue()));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private static Object isType(Field field, String value) throws ParseException {
        String fileType = field.getType().getName();
        String simpleDateFormat = null;
        if (String.valueOf(String.class.getName()).equalsIgnoreCase(field.getType().getName())) {
            return value;
        }

        if (String.valueOf(int.class.getName()).equalsIgnoreCase(fileType) || String.valueOf(Integer.class.getName()).equalsIgnoreCase(fileType)) {
            try {
                return Integer.parseInt(value);
            } catch (Exception e) {
                return 0;
            }
        }

        if (String.valueOf(double.class.getName()).equalsIgnoreCase(fileType) || String.valueOf(Double.class.getName()).equalsIgnoreCase(fileType)) {
            try {
                return Double.parseDouble(value);
            } catch (Exception e) {
                return 0.0;
            }
        }

        if (String.valueOf(long.class.getName()).equalsIgnoreCase(fileType) || String.valueOf(Long.class.getName()).equalsIgnoreCase(fileType)) {
            try {
                return Long.parseLong(value);
            } catch (Exception e) {
                return 0;
            }
        }

        if (String.valueOf(Date.class.getName()).equalsIgnoreCase(fileType)) {
            if (value == null || "".equals(value)) {
                return null;
            } else {
                Date date = null;
                String regex = "\\d{4}+-\\d{1,2}+-\\d{1,2}+";
                if (value.matches(regex)) {
                    try {
                        date = new SimpleDateFormat("yyyy-MM-dd").parse(value);
                    } catch (Exception e) {
                        return null;
                    }
                    return date;
                }
                regex = "\\d{4}+-\\d{1,2}+-\\d{1,2}+ \\d{1,2}+:\\d{1,2}+:\\d{1,2}+";
                if (value.matches(regex)) {
                    try {
                        date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(value);
                    } catch (Exception e) {
                        return null;
                    }
                    return date;
                }
            }
        }
        return null;
    }
}

结果:

BasketBall{name='篮球', brand='乔丹', price=199.0, buyCount=5, produce=100, testTime=Sun Mar 08 23:56:03 CST 2020, ball=Ball{name='球', brand='null', createDate=null, createCompany=CreateCompany{companyName='篮球公司', companyBrand='null', companyFoundDate=null}}}
Ball{name='球', brand='null', createDate=null, createCompany=CreateCompany{companyName='篮球公司', companyBrand='null', companyFoundDate=null}}
CreateCompany{companyName='篮球公司', companyBrand='null', companyFoundDate=null}

发布了61 篇原创文章 · 获赞 0 · 访问量 2173

猜你喜欢

转载自blog.csdn.net/sabstarb/article/details/104743892