Java反射Filed、Method、Constructor类_02

1. Field类

Field类中提供了操作变量的方式,可以对变量数据获取与设置,包括可以操作私有变量

1.2. Field类常用方法
  1. public Object get(Object obj):通过对象实例获取对象中属性的数据
    1. obj:是指定实例对象,可以通过Class的newInstance()方法获取,或使用Constructor构造方法
  2. public void set(Object obj, Object value):通过对象实例设置属性数据
    1. obj:是指定实例对象,可以通过Class的newInstance()方法获取,或使用Constructor构造方法
    2. value:属性的数据
  3. public void setAccessible(boolean flag):强制忽略安全检测调用获取非public修饰的属性
  4. public String getName():获取属性名称
  5. public Class<?> getType():获取属性类型
  6. public int getModifiers():获取属性修饰符
     // 通过Class.forName获取Class类
        Class<?> clazz = Class.forName("reflection.User");
        // 通过Class的newInstance方法获取User对象实例
        Object newInstance = clazz.newInstance();
        // 获取类中指定属性
        // 私有的
        Field id = clazz.getDeclaredField("id");
        // 公共的
        Field age = clazz.getDeclaredField("age");
        //1. `obj`:是指定要获取值的实例对象
        Object object = age.get(newInstance);
        System.out.println("object = " + object);
        // 2. `public void set(Object obj, Object value)`:通过对象实例设置属性数据
        // `obj`:是指定实例对象,可以通过Class的newInstance()方法获取,或使用Constructor构造方法
        // `value`:属性的数据
        age.set(newInstance, 18);
        object = age.get(newInstance);
        System.out.println("object = " + object);
        System.out.println("newInstance = " + newInstance);
        String name = age.getName();
        System.out.println("name = " + name);
        Class<?> type = age.getType();
        System.out.println("type = " + type);
        int modifiers = age.getModifiers();
        System.out.println("modifiers = " + modifiers);
        id.setAccessible(true);
        // 私有变量获取与设置
        Object object1 = id.get(newInstance);
        System.out.println("object1 = " + object1);
        id.set(newInstance, 111);
        object1 = id.get(newInstance);
        System.out.println("object1 = " + object1);
        System.out.println("newInstance = " + newInstance);

2. Method类

Method类中提供了操作方法的方式,可以对方法获取或调用,包括可以操作私有方法

2.1. Method类常用方法
  1. public String getName():获取方法名称
  2. public int getModifiers():获取方法修饰符
  3. public int getParameterCount():获取方法形参数量
  4. public Class<?> getReturnType():获取方法返回值类型
  5. public Class<?>[] getParameterTypes():获取方法形参类型
  6. public Object invoke(Object obj, Object... args):调用此方法
    1. obj:是指定实例对象,可以通过Class的newInstance()方法获取,或使用Constructor构造方法
    2. args:形参参数
  7. public void setAccessible(boolean flag):强制忽略安全检测调用获取非public修饰的属性
 		// 获取User实例对象
        Class<?> clazz = Class.forName("reflection.User");
        Object newInstance = clazz.newInstance();
        // 私有方法
        Method method1 = clazz.getDeclaredMethod("method", Integer.class);
        // 公共方法
        Method method2 = clazz.getDeclaredMethod("method", String.class, String.class);
        // 1. `public String getName()`:获取方法名称
        String name = method2.getName();
        System.out.println("name = " + name);
        // 2. `public int getModifiers()`:获取方法修饰符
        int modifiers = method2.getModifiers();
        System.out.println("modifiers = " + modifiers);
        // 3. `public int getParameterCount()`:获取方法形参数量
        int parameterCount = method2.getParameterCount();
        System.out.println("parameterCount = " + parameterCount);
        // 4. `public Class<?> getReturnType()`:获取方法返回值类型
        Class<?> returnType = method2.getReturnType();
        System.out.println("returnType = " + returnType);
        // 5. `public Class<?>[] getParameterTypes()`:获取方法形参类型
        Class<?>[] parameterTypes = method2.getParameterTypes();
        System.out.println("Arrays.toString(parameterTypes) = " + Arrays.toString(parameterTypes));
        // 6. `public Object invoke(Object obj, Object... args)`:调用此方法
        //     1. `obj`:是指定实例对象,可以通过Class的newInstance()方法获取,或使用Constructor构造方法
        //     2. `args`:形参参数
        System.out.println("====================================");
        Object returnValue = method2.invoke(newInstance, "彭于晏", "男");
        System.out.println("returnValue = " + returnValue);
        // 打印newInstance对象
        System.out.println("newInstance = " + newInstance);
        // 7. `public void setAccessible(boolean flag)`:强制忽略安全检测调用获取非public修饰的属性
        System.out.println("====================================");
        String name1 = method1.getName();
        System.out.println("name1 = " + name1);
        // 调用非public修饰的方法必须设置setAccessible忽略安全检测
        method1.setAccessible(true);
        method1.invoke(newInstance, 1);
        System.out.println("newInstance = " + newInstance);

3. Constructor类

Constructor类中提供了操作构造方法的方式,可以对构造方法获取或设置,包括可以操作私有的构造方法

3.1. Constructor类常用方法
  1. public String getName():获取构造方法名称
  2. public int getModifiers():获取构造方法修饰符
  3. public int getParameterCount():获取构造方法形参数量
  4. public Class<?>[] getParameterTypes():获取构造方法形参类型
  5. public T newInstance(Object ... initargs):调用构造方法,并指定形参数据
    1. initargs:形参参数
  6. public void setAccessible(boolean flag):强制忽略安全检测调用获取非public修饰的属性
		// 获取User实例对象
        Class<?> clazz = Class.forName("reflection.User");
		// 私有构造方法
        Constructor<?> constructor1 = clazz.getDeclaredConstructor(Integer.class);
        // 公共构造方法
        Constructor<?> constructor2 = clazz.getDeclaredConstructor(Integer.class, String.class, String.class, Integer.class);
        // 1. `public String getName()`:获取构造方法名称
        String name = constructor2.getName();
        System.out.println("name = " + name);
        // 2. `public int getModifiers()`:获取构造方法修饰符
        int modifiers = constructor2.getModifiers();
        System.out.println("modifiers = " + modifiers);
        // 3. `public int getParameterCount()`:获取构造方法形参数量
        int parameterCount = constructor2.getParameterCount();
        System.out.println("parameterCount = " + parameterCount);
        // 4. `public Class<?>[] getParameterTypes()`:获取构造方法形参类型
        Class<?>[] parameterTypes = constructor2.getParameterTypes();
        System.out.println("Arrays.toString(parameterTypes) = " + Arrays.toString(parameterTypes));
        // 5. `public T newInstance(Object ... initargs)`:调用构造方法,并指定形参数据
        //     1. `initargs`:形参参数
        System.out.println("====================================");
        Object instance = constructor2.newInstance(1, "彭于晏", "男", 18);
        System.out.println("instance = " + instance);
        // 6. `public void setAccessible(boolean flag)`:强制忽略安全检测调用获取非public修饰的属性
        System.out.println("====================================");
        int modifiers1 = constructor1.getModifiers();
        System.out.println("modifiers1 = " + modifiers1);
        // 调用私有的构造方法需要设置忽略安全检测
        constructor1.setAccessible(true);
        Object instance1 = constructor1.newInstance(1);
        System.out.println("instance1 = " + instance1);

Field、Method、Constructor结合使用

 public static void main(String[] args) throws Exception {
        // 获取Student的Class对象
        Class<?> clazz = Class.forName("reflection.Student");
        // 获取构造方法
        Constructor<?> constructor = clazz.getConstructor(Integer.class, String.class, String.class);
        // 创建User对象实例-->此实例也用于后面的方法和属性使用
        Object instance = constructor.newInstance(1, "古天乐", "男");
        System.out.println("instance = " + instance);
        // 获取属性
        Field id = clazz.getDeclaredField("id");
        Field name = clazz.getDeclaredField("name");
        Field gender = clazz.getDeclaredField("gender");
        // 设置setAccessible强制忽略安全检测调用非public修饰的属性
        id.setAccessible(true);
        name.setAccessible(true);
        gender.setAccessible(true);
        // 获取属性数据
        System.out.println("修改前");
        Object idValue = id.get(instance);
        System.out.println("idValue = " + idValue);
        Object nameValue = name.get(instance);
        System.out.println("nameValue = " + nameValue);
        Object genderValue = gender.get(instance);
        System.out.println("genderValue = " + genderValue);
        // 设置属性数据
        id.set(instance, 2);
        name.set(instance, "古校长");
        gender.set(instance, "男神");
        // 获取属性数据
        System.out.println("修改后");
        Object idValue1 = id.get(instance);
        System.out.println("idValue1 = " + idValue1);
        Object nameValue1 = name.get(instance);
        System.out.println("nameValue1 = " + nameValue1);
        Object genderValue1 = gender.get(instance);
        System.out.println("genderValue1 = " + genderValue1);
        // 获取方法
        // 获取get方法
        Method getIdMethod = clazz.getMethod("getId");
        Method getNameMethod = clazz.getMethod("getName");
        Method getGenderMethod = clazz.getMethod("getGender");
        // 调用方法
        System.out.println("修改前");
        Object result1 = getIdMethod.invoke(instance);
        System.out.println("result1 = " + result1);
        Object result2 = getNameMethod.invoke(instance);
        System.out.println("result2 = " + result2);
        Object result3 = getGenderMethod.invoke(instance);
        System.out.println("result3 = " + result3);
        // 获取set方法
        Method setIdMethod = clazz.getMethod("setId", Integer.class);
        Method setNameMethod = clazz.getMethod("setName", String.class);
        Method setGenderMethod = clazz.getMethod("setGender", String.class);
        // 调用方法
        setIdMethod.invoke(instance, 1);
        setNameMethod.invoke(instance, "古天乐");
        setGenderMethod.invoke(instance, "男神");
        // 调用方法
        System.out.println("修改后");
        result1 = getIdMethod.invoke(instance);
        System.out.println("result1 = " + result1);
        result2 = getNameMethod.invoke(instance);
        System.out.println("result2 = " + result2);
        result3 = getGenderMethod.invoke(instance);
        System.out.println("result3 = " + result3);
        // 获取toString方法并调用
        Method toString = clazz.getMethod("toString");
        Object result = toString.invoke(instance);
        System.out.println("result = " + result);
        System.out.println("instance = " + instance);
    }

4.JSON与Java对象互转工具类

/**
 * JSON互转工具类
 */
public class JSON {

    /**
     * Java对象转JSON字符串方法
     *
     * @param obj 传入需要转换的Java对象
     * @return 返回转换后的JSON字符串
     */
    public static String toJSONString(Object obj) {
        // 1. 获取传入的对象的Class类
        Class<?> clazz = obj.getClass();
        // 2. 获取所有的属性
        Field[] fields = clazz.getDeclaredFields();
        // 定义StringBuilder拼接字符串
        StringBuilder sb = new StringBuilder("{");
        // 3. 遍历所有的属性
        for (int i = 0; i < fields.length; i++) {
            // 4. 设置setAccessible强制忽略安全检测
            fields[i].setAccessible(true);
            try {
                // 5. 获取属性名称和属性值和属性类型
                Class<?> fieldType = fields[i].getType();
                String fieldName = fields[i].getName();
                Object fieldValue = fields[i].get(obj);
                // 6. 拼接JSON字符串
                // 判断属性类型是否是String
                if (fieldType == String.class) {
                    // 判断是否是最后一个属性
                    if (i == fields.length - 1) {
                        // 拼接数据
                        // {"age":18,"gender":"男","id":1,"name":"彭于晏"}
                        sb.append("\"" + fieldName + "\":" + "\"" + fieldValue + "\"}");
                        continue;
                    }
                    sb.append("\"" + fieldName + "\":" + "\"" + fieldValue + "\",");
                    continue;
                }
                // 判断是否是最后一个属性
                if (i == fields.length - 1) {
                    // 拼接数据
                    // {"age":18,"gender":"男","id":1,"name":"彭于晏"}
                    sb.append("\"" + fieldName + "\":" + "" + fieldValue + "}");
                    continue;
                }
                sb.append("\"" + fieldName + "\":" + "" + fieldValue + ",");
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return sb.toString();
    }

    /**
     * 将JSON字符串转为Java对象
     *
     * @param jsonString JSON字符串
     * @param clazz      需要转换的Class类型
     * @param <T>        泛型类型变量
     * @return 返回转换后的对象
     */
    public static <T> T parseObject(String jsonString, Class<T> clazz) {
        // 通过Class获取实例对象
        try {
            T instance = clazz.newInstance();
            // 解析JSON字符串
            // {"id":1,"name":"彭于晏","gender":"男"}
            // 去除JSON字符串的大括号以及双引号
            jsonString = jsonString
                    .replace("{", "")
                    .replace("}", "")
                    .replace("\"", "");
            // 逗号分割
            String[] split = jsonString.split(",");
            // 遍历split分割的数组
            for (String keyValue : split) {
                // 再通过冒号:分割
                String[] keyAndValue = keyValue.split(":");
                // 获取属性
                Field field = clazz.getDeclaredField(keyAndValue[0]);
                // 设置忽略安全检测
                field.setAccessible(true);
                // 获取属性的类型
                Class<?> fieldType = field.getType();
                // 判断type类型
                if (fieldType == String.class) {
                    field.set(instance, keyAndValue[1]);
                    continue;
                }
                // 如果不是String就是Integer
                field.set(instance, Integer.valueOf(keyAndValue[1]));
            }
            // 返回T泛型类型对象
            return instance;
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 如果出现异常则返回null
        return null;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值