【反射机制】

0.常用方法

0.1Class类

方法签名 核心作用 典型使用场景
Class<?> forName(String className) 全类名加载类(静态方法) 动态加载类(如 Class.forName("com.example.Student")
Class<?> getClass() 通过对象获取类对象 Student s = new Student(); Class<?> clazz = s.getClass();
Class<?> getSuperclass() 获取父类的 Class 对象 查看类的继承关系(如 clazz.getSuperclass()
Class<?>[] getInterfaces() 获取实现的所有接口 JDK 动态代理中指定接口(如 proxy.newProxyInstance(..., clazz.getInterfaces(), ...)
Field[] getFields() 获取所有公有(public) 属性 仅读取类的 public 成员变量
Field[] getDeclaredFields() 获取所有属性(包括 private/protected) 通用属性拷贝(如 DTO→VO 对拷)
Field getField(String name) 获取指定名称的公有属性 精准读取单个 public 属性
Field getDeclaredField(String name) 获取指定名称的任意属性 读取 / 修改 private 属性
Method[] getMethods() 获取所有公有方法(含父类继承的) 调用类的 public 方法
Method[] getDeclaredMethods() 获取所有方法(包括 private/protected) 调用类的私有方法
Method getMethod(String name, Class<?>... paramTypes) 获取指定名称 + 参数的公有方法 调用 public void login(String, String)
Method getDeclaredMethod(String name, Class<?>... paramTypes) 获取指定名称 + 参数的任意方法 调用 private 方法
Constructor<?>[] getConstructors() 获取所有公有构造器 创建公有构造器的实例
Constructor<?>[] getDeclaredConstructors() 获取所有构造器(包括私有) 创建私有构造器的单例对象
Constructor<T> getConstructor(Class<?>... paramTypes) 获取指定参数的公有构造器 Constructor<Student> c = clazz.getConstructor(String.class, int.class);
Constructor<T> getDeclaredConstructor(Class<?>... paramTypes) 获取指定参数的任意构造器 调用私有构造器(如单例模式)
T newInstance() 创建类的实例(无参构造) 简化实例化(JDK9 后标记为过时,推荐用构造器)
boolean isInstance(Object obj) 判断 obj 是否是该类的实例 替代 obj instanceof Class
boolean isAssignableFrom(Class<?> cls) 判断当前类是否是 cls 的父类 / 接口 类型兼容性判断(如 List.class.isAssignableFrom(ArrayList.class)

0.2Field类

方法签名 核心作用 典型使用场景
void setAccessible(boolean flag) 打破封装,允许访问私有属性 读写 private 属性(必须先调用)
Object get(Object obj) 从 obj 中获取该属性的值 DTO→VO 拷贝时读取源对象属性值
void set(Object obj, Object value) 给 obj 的该属性设置值 DTO→VO 拷贝时给目标对象赋值
String getName() 获取属性名称 遍历属性时打印 / 匹配属性名
Class<?> getType() 获取属性的类型(如 String/int) 属性拷贝时校验类型是否匹配
int getModifiers() 获取属性的修饰符(如 public/private) 判断属性是否是 static/final

0.3Method类

方法签名 核心作用 典型使用场景
void setAccessible(boolean flag) 允许调用私有方法 调用类的 private 方法
Object invoke(Object obj, Object... args) 调用 obj 的该方法,传入参数 args 动态代理中调用目标方法(method.invoke(target, args)
String getName() 获取方法名称 日志打印方法名(如 Before: + method.getName())
Class<?> getReturnType() 获取方法的返回值类型 校验方法返回值是否符合预期
Class<?>[] getParameterTypes() 获取方法的参数类型数组 动态匹配方法参数
int getModifiers() 获取方法的修饰符(如 public/static) 判断方法是否是 static/final

0.4Consturctor类

方法签名 核心作用 典型使用场景
void setAccessible(boolean flag) 允许调用私有构造器 创建单例类的实例(私有构造器)
T newInstance(Object... args) 通过构造器创建实例,传入参数 替代 Class.newInstance()(支持有参构造)
String getName() 获取构造器所属类的名称 日志打印构造器所属类
Class<?>[] getParameterTypes() 获取构造器的参数类型数组 匹配有参构造器的参数

一.运行时,动态创建需要的类

code:

java 复制代码
public class MyBeanFactoryImpl implements MyBeanFactory {
    @Value("${class.name}")
    String className;

    public String getClassName() {
        return className;
    }
    public Object getBean() throws Exception {
        Class<?> clazz = Class.forName(className);
        Constructor<?> constructor = clazz.getConstructor();
        return constructor.newInstance();
    }
}

二.交换两个相同类的属性值

java 复制代码
package org.example.reflect.MyBeanFactoryTest;

import org.example.reflect.bean.User;
import org.junit.jupiter.api.Test;

import java.lang.reflect.Field;

public class SwapTwoUserAttributionTest {
    @Test
    public void testSwapTwoUserAttribution() throws Exception {
        User user1 = new User("张三", 18, "男");
        User user2 = new User("李四", 19, "女");

        Field[] user1Fields = user1.getClass().getDeclaredFields();
        Field[] user2Fields = user2.getClass().getDeclaredFields();
        //交换两个相同类的属性值
        for (int i = 0; i < user1Fields.length; i++) {
            Field user1Field = user1Fields[i];
            Field user2Field = user2Fields[i];
            user1Field.setAccessible(true);
            user2Field.setAccessible(true);
            Object temp = user1Field.get(user1);
            user1Field.set(user1, user2Field.get(user2));
            user2Field.set(user2, temp);
        }
        System.out.println("交换后的两个对象:");
        System.out.println(user1);
        System.out.println(user2);
    }
}
相关推荐
XiYang-DING11 小时前
【Java EE】 TCP—异常情况处理
java·tcp/ip·java-ee
lianghyan11 小时前
List.stream().min
java·开发语言
Hello--_--World11 小时前
为什么 用vite进行分包后,可以通过 浏览器强制缓存 提高性能?路由懒加载进行的分包与 vite进行的分包有什么不同?
前端·javascript·缓存·vite
三*一11 小时前
Mapbox GL JS 前端多边形分割实战:从踩坑到优雅实现
开发语言·前端·javascript·vue.js
爱笑的源码基地11 小时前
小微企业ERP源码,采用SpringBoot+Vue+ElementUI+UniAPP技术架构,支持二次开发及商用授权
java·源码·二次开发·erp·源代码·mrp生产计划
一棵树735111 小时前
js总结介绍
前端·javascript·html
happymaker062611 小时前
Spring学习日记——DAY03(yml文件)
java·spring boot·spring
凯瑟琳.奥古斯特11 小时前
操作系统核心结构解析
java·开发语言·c++·python·职场和发展
ZC跨境爬虫11 小时前
跟着 MDN 学CSS day_2:(连接样式表与选择器的实战艺术)
java·前端·css·ui·html·媒体
敖正炀11 小时前
AQS-钩子方法
java