本文目录导读:

在Java中获取类的所有属性(字段或方法等),主要依赖于反射机制,以下是几种常见且实用的案例和实现方式。
核心API回顾
反射中用于获取属性的核心类和方法:
Class.getFields():获取所有 public 属性(包含父类继承的)。Class.getDeclaredFields():获取当前类中 所有访问权限 的属性(不包括父类)。Field类:代表一个属性,可获取名称、类型、修饰符等。
完整代码案例
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
public class FieldReflectionDemo {
// 示例父类
static class Animal {
public String species = "unknown";
private int age = 0;
}
// 示例子类
static class Dog extends Animal {
public String name = "旺财";
private String breed;
protected double weight;
String color; // 默认访问权限(包级别)
}
public static void main(String[] args) {
// 获取 Dog 类的所有属性
List<Field> allFields = getAllFields(Dog.class);
System.out.println("=== 获取 Dog 类所有属性(包括私有、父类) ===");
for (Field field : allFields) {
System.out.printf("字段名: %s | 类型: %s | 修饰符: %s%n",
field.getName(),
field.getType().getSimpleName(),
Modifier.toString(field.getModifiers()));
}
System.out.println("\n=== 仅获取当前类声明的所有属性(不包括父类) ===");
Field[] declaredFields = Dog.class.getDeclaredFields();
for (Field field : declaredFields) {
System.out.printf("字段名: %s | 类型: %s | 可访问: %s%n",
field.getName(),
field.getType().getSimpleName(),
field.canAccess(null)); // 默认不可访问私有字段
}
}
/**
* 获取类的所有属性(包括私有和继承的)
* @param clazz 目标类
* @return 属性列表
*/
public static List<Field> getAllFields(Class<?> clazz) {
List<Field> fields = new ArrayList<>();
// 递归遍历父类
while (clazz != null) {
for (Field field : clazz.getDeclaredFields()) {
// 排除 Object 类中的字段(一般不需要)
if (!"java.lang.Object".equals(clazz.getName())) {
fields.add(field);
}
}
clazz = clazz.getSuperclass();
}
return fields;
}
}
运行结果示例:
=== 获取 Dog 类所有属性(包括私有、父类) ===
字段名: name | 类型: String | 修饰符: public
字段名: breed | 类型: String | 修饰符: private
字段名: weight | 类型: double | 修饰符: protected
字段名: color | 类型: String | 修饰符:
字段名: species | 类型: String | 修饰符: public
字段名: age | 类型: int | 修饰符: private
注意:getDeclaredFields() 默认不会影响 private 字段的访问权限,若需要操作(读取/修改)私有字段,需调用 field.setAccessible(true)。
不同场景的获取方式对比
| 需求场景 | 推荐方法 | 注意事项 |
|---|---|---|
| 仅获取当前类所有字段(含私有) | getDeclaredFields() |
快速获取,不含父类字段 |
| 获取当前类及父类所有字段(常需要) | 手动递归 + getDeclaredFields() |
注意循环调用 getSuperclass(),避免包含 Object 类 |
| 获取所有 public 字段(含继承) | getFields() |
会包含父类 public 字段,但忽略私有字段 |
| 获取指定名称的字段 | getDeclaredField("fieldName") |
若字段不存在会抛 NoSuchFieldException |
高级用法:获取属性的完整信息
import java.lang.reflect.Field;
import java.lang.reflect.Type;
public class FieldDetailExample {
static class User {
public String username = "admin";
private int age = 25;
}
public static void main(String[] args) throws Exception {
User user = new User();
// 获取所有字段并打印详细信息
for (Field field : User.class.getDeclaredFields()) {
System.out.println("字段名: " + field.getName());
System.out.println("类型: " + field.getType().getSimpleName());
System.out.println("泛型类型: " + field.getGenericType());
System.out.println("是否为枚举常量: " + field.isEnumConstant());
// 动态获取字段值(注意私有字段需要 setAccessible)
field.setAccessible(true);
Object value = field.get(user);
System.out.println("当前值: " + value);
System.out.println("----------------------");
}
}
}
输出示例:
字段名: username
类型: String
泛型类型: class java.lang.String
是否为枚举常量: false
当前值: admin
----------------------
字段名: age
类型: int
泛型类型: int
是否为枚举常量: false
当前值: 25
----------------------
性能与安全建议
- 缓存反射结果:重复获取字段列表时,建议缓存(如用
Map<Class<?>, Field[]>),因为反射操作相对较慢。 - 设置可访问性控制:使用
setAccessible(true)后,记得在不再需要时还原为false,或只在无法避免时使用(某些环境有安全管理器限制)。 - 避免过度使用:在框架或库内部合理使用,业务代码中尽量用具体类的方法和属性,保持类型安全。
示例应用场景
| 应用场景 | 说明 |
|---|---|
| ORM框架(如MyBatis) | 通过字段名映射数据库列名 |
| JSON序列化/反序列化 | 获取所有字段进行动态处理 |
| 对象拷贝/克隆工具 | 遍历字段进行属性值复制 |
| 配置注入工具 | 检测配置类字段并赋值 |
| IDE调试器或日志工具 | 打印对象的完整属性状态 |
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播