MYSQL 之 JDBC(八):增删改查(六)ReflectionUtils

这里在网上找了一份ReflectionUtils

MYSQL 之 JDBC(八):增删改查(六)ReflectionUtils
package com.litian.jdbc;

/**
 * @author: Li Tian
 * @contact: litian_cup@163.com
 * @software: IntelliJ IDEA
 * @file: ReflectionUtils.java
 * @time: 2020/3/26 18:57
 * @desc: |JDBC 查询得到属性字段 反射机制返回到 JavaBean中相同类属性名的对象中
 */

import java.lang.reflect.*;


public class ReflectionUtils {

    /**
     * 使 filed 变为可访问
     *
     * @param field
     */
    public static void makeAccessible(Field field) {
        if (!Modifier.isPublic(field.getModifiers())) {
            field.setAccessible(true);
        }
    }

    /**
     * 直接设置对象的属性,忽略 private/protected 修饰符, 也不经过 setter
     *
     * @param object
     * @param fieldName 属性名称
     * @param value
     */
    public static void setFieldValue(Object object, String fieldName, Object value) {

        Field field = getDeclaredField(object, fieldName);
        if (field == null)
            throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + object + "]");

        // 让 private 元素变得可以访问,field.setAccessible();
        makeAccessible(field);

        try {
            field.set(object, value);
        } catch (IllegalArgumentException | IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /**
     * 循环向上转型, 获取对象的 DeclaredField
     *
     * @param object
     * @param filedName
     * @return
     */
    public static Field getDeclaredField(Object object, String filedName) {
        // 一步步的循环得到 获取声明对象的祖宗类
        for (Class<?> superClass = object.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) {
            try {
                return superClass.getDeclaredField(filedName);
            } catch (NoSuchFieldException | SecurityException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * 直接读取对象的属性值, 忽略 private/protected 修饰符, 也不经过 getter
     *
     * @param object
     * @param fieldName
     * @return
     */
    public static Object getFieldValue(Object object, String fieldName) {
        Field field = getDeclaredField(object, fieldName);

        if (field == null)
            throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + object + "]");

        makeAccessible(field);
        Object result = null;

        try {
            result = field.get(object);
        } catch (IllegalArgumentException | IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 循环向上转型, 获取对象的 DeclaredMethod
     *
     * @param object
     * @param methodName
     * @param parameterTypes: 指定特定成员方法有重载可能性,必须指定特定的类型变量
     * @return
     */
    public static Method getDeclaredMethod(Object object, String methodName, Class<?>[] parameterTypes) {
        for (Class<?> superClass = object.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) {
            try {
                //superClass.getMethod(methodName, parameterTypes);
                return superClass.getDeclaredMethod(methodName, parameterTypes);
            } catch (NoSuchMethodException e) {
                //Method 不在当前类定义, 继续向上转型
            }
            //..
        }

        return null;
    }

    /**
     * 直接调用对象方法, 而忽略修饰符(private, protected)
     *
     * @param object
     * @param methodName
     * @param parameterTypes
     * @param parameters
     * @return
     * @throws InvocationTargetException
     * @throws IllegalArgumentException
     */
    public static Object invokeMethod(Object object, String methodName, Class<?>[] parameterTypes,
                                      Object[] parameters) throws InvocationTargetException {
        Method method = getDeclaredMethod(object, methodName, parameterTypes);

        if (method == null)
            throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + object + "]");
        method.setAccessible(true);

        // 使用 method.invoke()方法进行运行
        try {
            method.invoke(object, parameters);
        } catch (IllegalAccessException | IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return method;
    }

    /**
     * 通过反射, 获得定义 Class 时声明的父类的泛型参数的类型
     * 如: public EmployeeDao extends BaseDao<Employee, String>
     *
     * @param clazz
     * @return
     */
    public static Class getSuperClassGenricType(Class clazz, int index) {
        Type genType = clazz.getGenericSuperclass();

        // 判定s是否是ParameterType相对应的
        if (!(genType instanceof ParameterizedType))
            return Object.class;

        // 强制转换 获取超类泛型参数实际类型,返回genType 是类的接口,基本类型或者void
        Type[] params = ((ParameterizedType) genType).getActualTypeArguments();

        if (index >= params.length || index < 0)
            return Object.class;

        if (!(params[index] instanceof Class))
            return Object.class;
        return (Class) params[index];
    }

    /**
     * 通过反射,获得Class定义中声明的父类的泛型参数的类型.
     * eg.
     * public UserDao extends HibernateDao<User>
     *
     * @param clazz The class to introspect
     * @return the first generic declaration, or Object.class if cannot be determined
     */
    @SuppressWarnings("unchecked")
    public static <T> Class<T> getSuperClassGenricType(final Class clazz) {
        return getSuperClassGenricType(clazz, 0);
    }
}
View Code

JAVA类属性

在JAVAEE中,JAVA类的属性通过getter,setter来定义:get(set)方法:去除get(或set)后,首字母小写即为该类的属性。

而之前的属性,即成员变量称之为字段。

操作java类的属性有一个工具包:beanutils(需要结合logging来用)

BeanUtils.setProperty()
BeanUtils.getProperty()
一般情况下,字段名和属性名都一致

通过该工具包可以将之前的ReflectionUtil替换为:BeanUtils.setProperty(entity, propertyName, value);

BeanUtils测试代码

package com.litian.jdbc;

import org.apache.commons.beanutils.BeanUtils;

import java.lang.reflect.InvocationTargetException;

/**
 * @author: Li Tian
 * @contact: litian_cup@163.com
 * @software: IntelliJ IDEA
 * @file: BeanUtilsTest.java
 * @time: 2020/3/27 15:37
 * @desc: |测试工具包beanutils
 */

public class BeanUtilsTest {
    public static void main(String[] args) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
        // 测试赋值操作
        Object obj = new User();
        System.out.println(obj);

        BeanUtils.setProperty(obj, "username", "二哈");
        System.out.println(obj);

        // 测试获取操作
        Object val = BeanUtils.getProperty(obj, "username");
        System.out.println(val);

    }
}

 

————————————————
版权声明:本文为CSDN博主「李英俊小朋友」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_21579045/article/details/105386353

MYSQL 之 JDBC(八):增删改查(六)ReflectionUtils

上一篇:MYSQL 之 JDBC(十二): 处理Blob


下一篇:MYSQL 之 JDBC(九):增删改查(七)DAO的补充和重构