反射中对类的属性、方法、构造器的相关操作
操作的实体类
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);
}
}
}