Skip to content

反射

Class类

获取Class对象

java
public class ClassDemo {
    public static void main(String[] args) throws Exception {
        // 方式1:类名.class
        Class<String> clazz1 = String.class;
        
        // 方式2:对象.getClass()
        String str = "Hello";
        Class<? extends String> clazz2 = str.getClass();
        
        // 方式3:Class.forName()
        Class<?> clazz3 = Class.forName("java.lang.String");
        
        // 基本类型
        Class<Integer> intClass = int.class;
        Class<Void> voidClass = void.class;
        
        // 数组类型
        Class<int[]> intArrayClass = int[].class;
        Class<String[]> stringArrayClass = String[].class;
    }
}

Class类方法

java
Class<?> clazz = String.class;

// 类信息
clazz.getName();          // java.lang.String
clazz.getSimpleName();    // String
clazz.getPackage();       // java.lang
clazz.getSuperclass();    // class java.lang.Object
clazz.getInterfaces();    // 实现的接口
clazz.getModifiers();     // 修饰符

// 成员
clazz.getFields();        // 公共字段(包括继承)
clazz.getDeclaredFields(); // 所有字段(不包括继承)
clazz.getMethods();       // 公共方法(包括继承)
clazz.getDeclaredMethods(); // 所有方法(不包括继承)
clazz.getConstructors();  // 公共构造方法
clazz.getDeclaredConstructors(); // 所有构造方法

// 创建实例
clazz.newInstance();      // 已废弃
clazz.getDeclaredConstructor().newInstance();

获取类信息

获取字段

java
import java.lang.reflect.Field;

public class FieldDemo {
    public static void main(String[] args) throws Exception {
        Class<?> clazz = Person.class;
        
        // 获取所有公共字段
        Field[] fields = clazz.getFields();
        
        // 获取所有声明的字段
        Field[] declaredFields = clazz.getDeclaredFields();
        
        // 获取指定字段
        Field nameField = clazz.getDeclaredField("name");
        
        // 字段信息
        System.out.println("字段名: " + nameField.getName());
        System.out.println("类型: " + nameField.getType());
        System.out.println("修饰符: " + Modifier.toString(nameField.getModifiers()));
    }
}

class Person {
    public String name;
    private int age;
    protected String address;
}

获取方法

java
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class MethodDemo {
    public static void main(String[] args) throws Exception {
        Class<?> clazz = String.class;
        
        // 获取所有公共方法
        Method[] methods = clazz.getMethods();
        
        // 获取所有声明的方法
        Method[] declaredMethods = clazz.getDeclaredMethods();
        
        // 获取指定方法
        Method substringMethod = clazz.getMethod("substring", int.class, int.class);
        
        // 方法信息
        System.out.println("方法名: " + substringMethod.getName());
        System.out.println("返回类型: " + substringMethod.getReturnType());
        System.out.println("参数类型: " + 
            Arrays.toString(substringMethod.getParameterTypes()));
        System.out.println("修饰符: " + 
            Modifier.toString(substringMethod.getModifiers()));
    }
}

获取构造方法

java
import java.lang.reflect.Constructor;

public class ConstructorDemo {
    public static void main(String[] args) throws Exception {
        Class<?> clazz = String.class;
        
        // 获取所有公共构造方法
        Constructor<?>[] constructors = clazz.getConstructors();
        
        // 获取所有声明的构造方法
        Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors();
        
        // 获取指定构造方法
        Constructor<String> constructor = clazz.getConstructor(byte[].class);
        
        // 构造方法信息
        System.out.println("名称: " + constructor.getName());
        System.out.println("参数数量: " + constructor.getParameterCount());
    }
}

创建对象

通过构造方法创建

java
public class CreateObjectDemo {
    public static void main(String[] args) throws Exception {
        Class<?> clazz = Person.class;
        
        // 使用无参构造
        Person p1 = (Person) clazz.getDeclaredConstructor().newInstance();
        
        // 使用有参构造
        Constructor<?> constructor = clazz.getDeclaredConstructor(String.class, int.class);
        Person p2 = (Person) constructor.newInstance("张三", 25);
        
        System.out.println(p2);
    }
}

class Person {
    private String name;
    private int age;
    
    public Person() { }
    
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    @Override
    public String toString() {
        return "Person{name='" + name + "', age=" + age + "}";
    }
}

调用方法

java
import java.lang.reflect.Method;

public class InvokeMethodDemo {
    public static void main(String[] args) throws Exception {
        Person person = new Person("张三", 25);
        Class<?> clazz = person.getClass();
        
        // 获取方法
        Method setNameMethod = clazz.getDeclaredMethod("setName", String.class);
        Method getNameMethod = clazz.getDeclaredMethod("getName");
        
        // 调用方法
        setNameMethod.invoke(person, "李四");
        String name = (String) getNameMethod.invoke(person);
        System.out.println(name);  // 李四
        
        // 调用私有方法
        Method privateMethod = clazz.getDeclaredMethod("privateMethod");
        privateMethod.setAccessible(true);  // 突破访问限制
        privateMethod.invoke(person);
        
        // 调用静态方法
        Method staticMethod = clazz.getDeclaredMethod("staticMethod");
        staticMethod.invoke(null);  // 静态方法,对象传null
    }
}

class Person {
    private String name;
    private int age;
    
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    
    private void privateMethod() {
        System.out.println("私有方法");
    }
    
    public static void staticMethod() {
        System.out.println("静态方法");
    }
}

访问字段

java
import java.lang.reflect.Field;

public class AccessFieldDemo {
    public static void main(String[] args) throws Exception {
        Person person = new Person("张三", 25);
        Class<?> clazz = person.getClass();
        
        // 获取字段
        Field nameField = clazz.getDeclaredField("name");
        Field ageField = clazz.getDeclaredField("age");
        
        // 突破访问限制
        nameField.setAccessible(true);
        ageField.setAccessible(true);
        
        // 获取字段值
        String name = (String) nameField.get(person);
        int age = ageField.getInt(person);
        System.out.println(name + ", " + age);
        
        // 设置字段值
        nameField.set(person, "李四");
        ageField.setInt(person, 30);
        System.out.println(person);
    }
}

动态代理

JDK动态代理

java
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class JdkProxyDemo {
    public static void main(String[] args) {
        // 创建目标对象
        UserService target = new UserServiceImpl();
        
        // 创建代理对象
        UserService proxy = (UserService) Proxy.newProxyInstance(
            target.getClass().getClassLoader(),
            target.getClass().getInterfaces(),
            new LogInvocationHandler(target)
        );
        
        // 调用代理方法
        proxy.addUser("张三");
        proxy.deleteUser(1);
    }
}

interface UserService {
    void addUser(String name);
    void deleteUser(int id);
}

class UserServiceImpl implements UserService {
    @Override
    public void addUser(String name) {
        System.out.println("添加用户: " + name);
    }
    
    @Override
    public void deleteUser(int id) {
        System.out.println("删除用户: " + id);
    }
}

class LogInvocationHandler implements InvocationHandler {
    private Object target;
    
    public LogInvocationHandler(Object target) {
        this.target = target;
    }
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("调用方法: " + method.getName());
        long start = System.currentTimeMillis();
        
        Object result = method.invoke(target, args);
        
        long end = System.currentTimeMillis();
        System.out.println("执行时间: " + (end - start) + "ms");
        
        return result;
    }
}

通用代理工厂

java
import java.lang.reflect.Proxy;

public class ProxyFactory {
    @SuppressWarnings("unchecked")
    public static <T> T createProxy(T target) {
        return (T) Proxy.newProxyInstance(
            target.getClass().getClassLoader(),
            target.getClass().getInterfaces(),
            (proxy, method, args) -> {
                System.out.println("Before: " + method.getName());
                try {
                    Object result = method.invoke(target, args);
                    System.out.println("After: " + method.getName());
                    return result;
                } catch (Exception e) {
                    System.out.println("Exception: " + e.getMessage());
                    throw e;
                }
            }
        );
    }
}

反射实战

工具类:复制对象属性

java
import java.lang.reflect.Field;

public class BeanUtils {
    public static void copyProperties(Object source, Object target) {
        Class<?> sourceClass = source.getClass();
        Class<?> targetClass = target.getClass();
        
        Field[] sourceFields = sourceClass.getDeclaredFields();
        
        for (Field sourceField : sourceFields) {
            try {
                Field targetField = targetClass.getDeclaredField(sourceField.getName());
                if (targetField.getType().equals(sourceField.getType())) {
                    sourceField.setAccessible(true);
                    targetField.setAccessible(true);
                    targetField.set(target, sourceField.get(source));
                }
            } catch (NoSuchFieldException e) {
                // 目标类没有该字段,跳过
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

工具类:对象转Map

java
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class ObjectToMap {
    public static Map<String, Object> toMap(Object obj) {
        Map<String, Object> map = new HashMap<>();
        Class<?> clazz = obj.getClass();
        
        for (Field field : clazz.getDeclaredFields()) {
            field.setAccessible(true);
            try {
                map.put(field.getName(), field.get(obj));
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        }
        return map;
    }
}

反射性能

性能优化

java
import java.lang.reflect.Method;

public class ReflectionPerformance {
    public static void main(String[] args) throws Exception {
        String str = "Hello";
        Method method = String.class.getMethod("length");
        
        // 普通调用
        long start = System.nanoTime();
        for (int i = 0; i < 1000000; i++) {
            str.length();
        }
        System.out.println("直接调用: " + (System.nanoTime() - start) + "ns");
        
        // 反射调用
        start = System.nanoTime();
        for (int i = 0; i < 1000000; i++) {
            method.invoke(str);
        }
        System.out.println("反射调用: " + (System.nanoTime() - start) + "ns");
        
        // 设置accessible可提升性能
        method.setAccessible(true);
        start = System.nanoTime();
        for (int i = 0; i < 1000000; i++) {
            method.invoke(str);
        }
        System.out.println("反射调用(setAccessible): " + (System.nanoTime() - start) + "ns");
    }
}

注意

反射会带来性能开销,应谨慎使用。在性能敏感的场景,考虑使用缓存Method对象或使用代码生成工具。