本文目录导读:

我来详细讲解Java中如何通过反射获取类信息,包括各种核心API的使用方法。
获取Class对象
public class ReflectionDemo {
public static void main(String[] args) throws Exception {
// 方式1:通过Class.forName()
Class<?> clazz1 = Class.forName("com.example.User");
// 方式2:通过对象.getClass()
User user = new User();
Class<?> clazz2 = user.getClass();
// 方式3:通过类.class
Class<?> clazz3 = User.class;
// 方式4:通过类加载器
Class<?> clazz4 = ClassLoader.getSystemClassLoader().loadClass("com.example.User");
}
}
获取类基本信息
public class ClassInfoDemo {
public static void main(String[] args) throws Exception {
Class<?> clazz = User.class;
// 获取类名
System.out.println("完整类名:" + clazz.getName()); // com.example.User
System.out.println("简单类名:" + clazz.getSimpleName()); // User
System.out.println("包名:" + clazz.getPackage().getName()); // com.example
// 获取访问修饰符
int modifiers = clazz.getModifiers();
System.out.println("修饰符:" + Modifier.toString(modifiers));
// 获取父类
Class<?> superClass = clazz.getSuperclass();
System.out.println("父类:" + superClass.getName());
// 获取实现的接口
Class<?>[] interfaces = clazz.getInterfaces();
for (Class<?> inter : interfaces) {
System.out.println("实现的接口:" + inter.getName());
}
}
}
获取类的成员信息
1 获取字段(Field)
public class FieldInfoDemo {
public static void main(String[] args) throws Exception {
Class<?> clazz = User.class;
// 获取所有公共字段(包括继承的)
Field[] publicFields = clazz.getFields();
// 获取所有字段(不包括继承的)
Field[] allFields = clazz.getDeclaredFields();
for (Field field : allFields) {
System.out.println("字段名:" + field.getName());
System.out.println("字段类型:" + field.getType().getName());
System.out.println("修饰符:" + Modifier.toString(field.getModifiers()));
// 处理私有字段
field.setAccessible(true);
User user = new User();
if (field.getName().equals("name")) {
field.set(user, "张三");
System.out.println("设置值后:" + field.get(user));
}
}
}
}
2 获取方法(Method)
public class MethodInfoDemo {
public static void main(String[] args) throws Exception {
Class<?> clazz = User.class;
// 获取所有公共方法(包括继承的)
Method[] publicMethods = clazz.getMethods();
// 获取所有方法(不包括继承的)
Method[] allMethods = clazz.getDeclaredMethods();
for (Method method : allMethods) {
System.out.println("方法名:" + method.getName());
System.out.println("返回类型:" + method.getReturnType().getName());
System.out.println("修饰符:" + Modifier.toString(method.getModifiers()));
// 获取参数类型
Class<?>[] paramTypes = method.getParameterTypes();
for (Class<?> paramType : paramTypes) {
System.out.println("参数类型:" + paramType.getName());
}
// 获取异常类型
Class<?>[] exceptionTypes = method.getExceptionTypes();
for (Class<?> exType : exceptionTypes) {
System.out.println("抛出异常:" + exType.getName());
}
}
// 调用方法
User user = new User();
Method setNameMethod = clazz.getMethod("setName", String.class);
setNameMethod.invoke(user, "李四");
Method getNameMethod = clazz.getMethod("getName");
String name = (String) getNameMethod.invoke(user);
System.out.println("调用方法结果:" + name);
}
}
3 获取构造方法(Constructor)
public class ConstructorInfoDemo {
public static void main(String[] args) throws Exception {
Class<?> clazz = User.class;
// 获取所有公共构造方法
Constructor<?>[] publicConstructors = clazz.getConstructors();
// 获取所有构造方法
Constructor<?>[] allConstructors = clazz.getDeclaredConstructors();
for (Constructor<?> constructor : allConstructors) {
System.out.println("构造方法名:" + constructor.getName());
// 获取参数类型
Class<?>[] paramTypes = constructor.getParameterTypes();
for (int i = 0; i < paramTypes.length; i++) {
System.out.println("参数" + i + "类型:" + paramTypes[i].getName());
}
}
// 通过构造方法创建对象
// 无参构造
User user1 = (User) clazz.getConstructor().newInstance();
// 有参构造
Constructor<?> constructor = clazz.getConstructor(String.class, int.class);
User user2 = (User) constructor.newInstance("王五", 25);
}
}
获取注解信息
public class AnnotationInfoDemo {
public static void main(String[] args) throws Exception {
Class<?> clazz = AnnotatedUser.class;
// 获取类上的注解
Annotation[] classAnnotations = clazz.getAnnotations();
if (clazz.isAnnotationPresent(Deprecated.class)) {
System.out.println("该类被标记为@Deprecated");
}
// 获取字段上的注解
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(MyAnnotation.class)) {
MyAnnotation annotation = field.getAnnotation(MyAnnotation.class);
System.out.println("字段:" + field.getName() +
" 注解值:" + annotation.value());
}
}
// 获取方法上的注解
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
if (method.isAnnotationPresent(Override.class)) {
System.out.println("方法:" + method.getName() + " 使用了@Override");
}
}
}
}
完整示例代码
// 示例类
class User {
private String name;
private int age;
public User() {}
public User(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
private void privateMethod() {
System.out.println("私有方法被调用");
}
@Override
public String toString() {
return "User{name='" + name + "', age=" + age + "}";
}
}
// 反射工具类
public class ReflectionUtils {
// 打印类的完整信息
public static void printClassInfo(Class<?> clazz) {
System.out.println("========== " + clazz.getName() + " 类信息 ==========");
// 基本类信息
System.out.println("包名:" + clazz.getPackage().getName());
System.out.println("修饰符:" + Modifier.toString(clazz.getModifiers()));
System.out.println("父类:" + clazz.getSuperclass().getName());
// 接口信息
System.out.println("\n实现的接口:");
for (Class<?> inter : clazz.getInterfaces()) {
System.out.println(" - " + inter.getName());
}
// 字段信息
System.out.println("\n所有字段:");
for (Field field : clazz.getDeclaredFields()) {
System.out.println(" " + Modifier.toString(field.getModifiers()) +
" " + field.getType().getSimpleName() +
" " + field.getName());
}
// 构造方法信息
System.out.println("\n所有构造方法:");
for (Constructor<?> constructor : clazz.getDeclaredConstructors()) {
System.out.print(" " + Modifier.toString(constructor.getModifiers()) +
" " + constructor.getName() + "(");
Class<?>[] paramTypes = constructor.getParameterTypes();
for (int i = 0; i < paramTypes.length; i++) {
System.out.print(paramTypes[i].getSimpleName());
if (i < paramTypes.length - 1) {
System.out.print(", ");
}
}
System.out.println(")");
}
// 方法信息
System.out.println("\n所有方法:");
for (Method method : clazz.getDeclaredMethods()) {
System.out.print(" " + Modifier.toString(method.getModifiers()) +
" " + method.getReturnType().getSimpleName() +
" " + method.getName() + "(");
Class<?>[] paramTypes = method.getParameterTypes();
for (int i = 0; i < paramTypes.length; i++) {
System.out.print(paramTypes[i].getSimpleName());
if (i < paramTypes.length - 1) {
System.out.print(", ");
}
}
System.out.println(")");
}
}
// 动态调用方法
public static Object invokeMethod(Object obj, String methodName,
Object... args) throws Exception {
Class<?> clazz = obj.getClass();
Class<?>[] paramTypes = new Class[args.length];
for (int i = 0; i < args.length; i++) {
paramTypes[i] = args[i].getClass();
}
Method method = clazz.getMethod(methodName, paramTypes);
return method.invoke(obj, args);
}
}
// 测试类
public class Main {
public static void main(String[] args) throws Exception {
// 打印类信息
ReflectionUtils.printClassInfo(User.class);
// 动态创建对象
Class<?> clazz = User.class;
User user = (User) clazz.getConstructor(String.class, int.class)
.newInstance("小明", 20);
// 动态调用方法
String result = (String) ReflectionUtils.invokeMethod(user, "getName");
System.out.println("\n动态调用结果:" + result);
// 修改私有字段
Field nameField = clazz.getDeclaredField("name");
nameField.setAccessible(true);
nameField.set(user, "小红");
System.out.println("修改私有字段后:" + user);
}
}
注意事项
- 性能开销:反射操作比直接调用慢,避免在循环中频繁使用
- 安全检查:访问私有成员时需要使用
setAccessible(true) - 异常处理:反射操作会抛出多个受检异常,需要适当处理
- 安全问题:反射可以绕过访问控制,可能破坏封装性
- 泛型信息:运行时泛型信息会被擦除,需要特殊处理
通过反射,你可以实现灵活的代码,适合框架开发、动态代理、序列化等场景。