Java反射工具类

package com.em.reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * Created by Administrator on 2018/9/24.
 */
public class ReflectUtils {

    /**
     * 反射出对象的两种方式:
     * 1. Class.forName()
     * 2.通过构造方法
     */


    public static <T> T newInstance(Class<T> clazz) throws IllegalAccessException, InstantiationException {
        if (clazz != null) {
            T t = clazz.newInstance();
            return t;
        }
        return null;
    }

    public static <T> T newInstanceByConstructor(Class<? extends T> clazz, Object... paramsObjects) throws IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchMethodException {
//        clazz.getDeclaredConstructors() 得到所有修饰符的构造方法,包括private
//        clazz.getConstructors(); 得到public修饰的构造方法
        Constructor[] construtors = clazz.getDeclaredConstructors();
        for (Constructor constructor : construtors) {
            Class[] parameterTypeClass = constructor.getParameterTypes();
            if (parameterTypeClass.length == paramsObjects.length) {
                for (int i = 0; i < parameterTypeClass.length; i++) {
                    if (parameterTypeClass[i] == paramsObjects[i].getClass())
                        break;
                }
                constructor.setAccessible(true);
                return (T) constructor.newInstance(paramsObjects);
            }
        }
        throw new NoSuchMethodException();
    }

    /**
     * 获取传入对象的字段值,含父类
     */
    public static Object getFieldValue(Object obj, String fieldName) throws NoSuchFieldException, IllegalAccessException {
        if (obj == null)
            return null;
        if (fieldName == null || fieldName.trim().equals(""))
            throw new IllegalArgumentException("fieldName is null");
        Class clazz = obj.getClass();
        Field field = null;
        while (clazz != null) {
            try {
                field = clazz.getDeclaredField(fieldName);
            } catch (NoSuchFieldException e) {
                clazz = clazz.getSuperclass();
            }
            if (field != null) {
                break;
            }
        }

        if (field == null) {
            throw new NoSuchFieldException();
        }

        field.setAccessible(true);  //设为true可以访问受限制的变量,默认为false ,这样将会破坏访问规则,但是某些时候却必须要访问(序列化、持久化)
        return field.get(obj);
    }

    public static boolean setFieldValue(Object obj, String fieldName, Object value) throws NoSuchFieldException, IllegalAccessException {
        if (obj == null)
            return false;
        if (fieldName == null || fieldName.trim().equals(""))
            return false;
        Field field = null;
        Class clazz = obj.getClass();
        while (clazz != null) {
            try {
                field = clazz.getDeclaredField(fieldName);
            } catch (NoSuchFieldException e) {
                clazz = clazz.getSuperclass();
            }
            if (field != null) {
                break;
            }
        }

        if (field == null) {
            throw new NoSuchFieldException();
        }

        field.setAccessible(true);
        field.set(obj, value);
        return true;
    }

    /**
     * 调用某个对象的方法,包括静态方法
     */
    public static Object invoke(Object obj, String methodName, Object... paramValues) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
        if (obj == null)
            throw new NullPointerException();
        if (methodName == null || methodName.trim().equals(""))
            return new NullPointerException();

        Method[] methods = obj.getClass().getDeclaredMethods();
        for (Method method : methods) {
            if (method.getName().equals(methodName)) {
                Class[] paramClazz = method.getParameterTypes();
                if (paramClazz != null && paramClazz.length == paramValues.length) {
                    for (int i = 0; i < paramClazz.length; i++) {
                        if (!paramClazz[i].equals(paramValues[i].getClass()))
                            break;
                    }
                    method.setAccessible(true);
                    return method.invoke(obj, paramValues);
                }
            }
        }
        throw new NoSuchMethodException();
    }


    public static void main(String[] args) {
//        FinalFiledClass finalFiledClass = reflect(FinalFiledClass.class);
//        FinalFiledClass finalFiledClass = reflectByConstructor(FinalFiledClass.class, true, "zhangsan", 23);
        FinalFiledClass finalFiledClass = null;
        try {
            finalFiledClass = newInstanceByConstructor(FinalFiledClass.class, "zhangsan", 23);
//            finalFiledClass = reflectByConstructor(FinalFiledClass.class, true);
//            System.out.println(finalFiledClass);
//            Object value = getFieldValue(finalFiledClass, "username");
//            System.out.println(value);
//            String name = "zhangyangyang";
//            setFieldValue(finalFiledClass, "username", name);
//            value = getFieldValue(finalFiledClass, "username");
//            System.out.println(value);


            System.out.println(invoke(finalFiledClass, "test", "lisi",33));

        } catch (Exception e) {
            e.printStackTrace();
        }


    }


}




Java 反射工具类 ReflectUtils 是一个提供了便捷的反射操作方法的工具类。它封装了 Java 反射 API 的一些常用功能,使得开发者能够更加方便地使用反射进行、方法、字段的操作。 ReflectUtils 提供了以下几个方法: 1. getTypeArguments:通过反射获取指定的泛型型参数。可以通过该方法来获取泛型型的具体参数型,方便在运行时进行型判断和操作。 2. invokeGetter:通过反射调用指定对象的指定字段的 getter 方法。在无法直接访问字段或需要动态调用字段的 getter 方法时,可以使用该方法。 3. invokeSetter:通过反射调用指定对象的指定字段的 setter 方法。在无法直接访问字段或需要动态调用字段的 setter 方法时,可以使用该方法。 4. getFieldValue:通过反射获取指定对象的指定字段的值。在无法直接访问字段时,可以使用该方法获取字段的值。 5. setFieldValue:通过反射设置指定对象的指定字段的值。在无法直接访问字段时,可以使用该方法设置字段的值。 6. getField:通过反射获取指定的指定字段。可以用于获取字段的修饰符、型等信息。 7. getMethod:通过反射获取指定的指定方法。可以用于获取方法的修饰符、返回值型、参数型等信息。 ReflectUtils 的使用能够简化反射操作的代码,提高开发效率,但也需要注意合理使用,避免引入不必要的复杂性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值