反射中对类的属性、方法、构造器的相关操作

反射中对类的属性、方法、构造器的相关操作


操作的实体类

package com.sai.reflet;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author cuiss
 * @Date 2025-03-24 09:37
 * @Description
 **/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {

    private Integer id;

    private String name;
}

测试代码

package com.sai.reflet;

import lombok.extern.slf4j.Slf4j;

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

/**
 * @author cuiss
 * @Date 2025-03-24 09:38
 * @Description 测试 反射中对类的属性、方法、构造器的相关操作
 **/
@Slf4j
public class TestUser {

    static User user = new User(1, "张三");

    /**
     * 通过反射获取类的 指定属性和值
     */
    @org.junit.jupiter.api.Test
    public void test1() {
        try {
            // 1. 获取Class对象
            Class<? extends User> reClass = User.class;

            // 2. 获取私有Field对象
            Field nameField = reClass.getDeclaredField("name");

            // 3. 设置可访问性(对私有属性必须)
            nameField.setAccessible(true);

            // 4. 创建实例(如果是静态属性则不需要)--- 这里引用静态已经创建好的实例
            User entity = user;

            // 5. 获取属性值
            Object value = nameField.get(entity);

            log.info("获取Class对象的指定私有属性值:name {}", value);
        } catch (NoSuchFieldException | IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 通过反射获取类的 所有属性和值
     */
    @org.junit.jupiter.api.Test
    public void test2() {
        Class<? extends User> reClass = user.getClass();

        log.info("类名:{}", reClass.getName());
        log.info("所有属性及值:");

        // 获取所有声明的字段(包括私有字段)
        Field[] fields = reClass.getDeclaredFields();
        for (Field field : fields) {
            try {
                // 设置可访问性以访问私有字段
                field.setAccessible(true);

                // 获取字段名
                String name = field.getName();

                // 获取字段值
                Object value = field.get(user);

                // 获取字段类型
                Class<?> type = field.getType();

                // 打印字段信息
                log.info("字段名: {} 类型: {} 值: {}", name, type.getSimpleName(), value);
            } catch (IllegalAccessException e) {
                System.out.println("无法访问字段: " + field.getName() + " - " + e.getMessage());
            }
        }
    }

    /**
     * 通过反射获取类的 指定方法并调用
     */
    @org.junit.jupiter.api.Test
    public void test3() {
        try {
            // 1. 获取Class对象
            Class<? extends User> reClass = user.getClass();

            // 2. 获取指定方法(getName)
            Method getName = reClass.getMethod("getName");

            // 3. 调用方法
            Object value = getName.invoke(user);

            // 4. 输出结果
            log.info("通过反射获取类的 指定方法(getName)并调用:{}", value);
        } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 通过反射获取类的 所有方法并调用
     */
    @org.junit.jupiter.api.Test
    public void test4() {
        try {
            // 1. 获取Class对象
            Class<? extends User> reClass = user.getClass();

            // 2. 获取指定方法(getName)
            //    获取所有声明的方法(不包括继承的方法) reClass.getDeclaredMethods();
            Method[] getNames = reClass.getMethods();
            log.info("获取类:{} 的所有公共方法", reClass.getName());

            // 3. 循环处理
            for (Method method : getNames) {
                System.out.println("方法名: " + method.getName());

                // 如果是getName方法就调用
                if ("getName".equals(method.getName()) &&
                        method.getParameterCount() == 0) {

                    Object result = method.invoke(user);
                    System.out.println("调用结果: " + result);
                }
            }
        } catch (InvocationTargetException | IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 通过反射获取类的 构造器并实例化
     * 方式一:使用 Class.newInstance()(已废弃,Java 9+ 不建议使用)
     * 只能调用无参构造器,且构造器必须是可访问的(非 private)。
     * 如果无参构造器不存在或不可访问,会抛出 InstantiationException 或 IllegalAccessException。
     */
    @org.junit.jupiter.api.Test
    public void test5() {
        try {
            // 方式一:.class
            Class<User> userClass = User.class;
            User user = userClass.newInstance();
            log.info("通过反射获取类的 构造器并实例化  无参构造  方式一:  User:{}", user);

            // 方式二:forName(String className)
            Class<?> userClass2 = Class.forName("com.sai.reflet.User");
            User user2 = (User) userClass2.newInstance();
            log.info("通过反射获取类的 构造器并实例化  无参构造  方式二:  User:{}", user2);
        } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 通过反射获取类的 构造器并实例化
     * 方式二:使用 Constructor.newInstance()(推荐方式)
     * getConstructor(Class<?>... paramTypes):获取公共构造器(public)。
     * getDeclaredConstructor(Class<?>... paramTypes):获取任意权限的构造器(包括 private)。
     * 如果构造器是 private 的,需要先调用 constructor.setAccessible(true)。
     */
    @org.junit.jupiter.api.Test
    public void test6() {
        try {
            // 无参构造
            Class<User> userClass = User.class;
            Constructor<User> constructor = userClass.getConstructor();
            User user = constructor.newInstance();

            // 有参构造
            Class<User> userClassY = User.class;
            Constructor<User> constructorY = userClassY.getConstructor(Integer.class, String.class);
            User userY = constructorY.newInstance(666, "豹子");

            log.info("无参构造  User:{}", user);
            log.info("有参构造  User:{}", userY);
        } catch (NoSuchMethodException | InvocationTargetException | InstantiationException |
                 IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 通过反射获取类的 属性的 可访问标志
     */
    @org.junit.jupiter.api.Test
    public void test7() {
        try {
            // 1. 获取Class对象
            Class<? extends User> reClass = User.class;

            // 2. 获取私有Field对象
            Field nameField = reClass.getDeclaredField("name");

            // 3. 检查并设置可访问标志
            boolean accessible = nameField.isAccessible();
            if (!accessible) {
                nameField.setAccessible(true);
            }
        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 通过反射获取类的 方法的 可访问标志
     */
    @org.junit.jupiter.api.Test
    public void test8() {
        try {
            // 1. 获取Class对象
            Class<? extends User> reClass = user.getClass();

            // 2. 获取指定方法(getName)
            Method getName = reClass.getMethod("getName");

            // 3. 检查并设置可访问标志
            boolean accessible = getName.isAccessible();
            if (!accessible) {
                getName.setAccessible(true);
            }
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        }
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值