03-Java语言核心-语法特性-反射机制详解

6 阅读14分钟

反射机制详解

一、知识概述

反射(Reflection)是Java语言的特性之一,它允许程序在运行时获取类的内部信息,并直接操作对象的属性和方法。反射是框架开发的基石,Spring、MyBatis、Hibernate等主流框架都大量依赖反射机制。

反射能做什么?

功能说明
获取类信息类名、修饰符、父类、接口、注解
操作字段获取字段、修改字段值(包括私有字段)
调用方法调用任意方法(包括私有方法)
创建对象无需new关键字,动态创建实例
动态代理运行时生成代理类

反射的应用场景

  • 框架开发:Spring IoC、AOP
  • ORM映射:Hibernate、MyBatis
  • 序列化/反序列化:Jackson、Gson
  • 动态代理:Retrofit、动态数据源
  • 测试框架:JUnit、Mockito

二、知识点详细讲解

2.1 获取Class对象

Class对象是反射的入口,有四种获取方式:

/**
 * 获取Class对象的四种方式
 */
public class GetClassDemo {
    public static void main(String[] args) throws Exception {
        // 方式1:通过类名.class(编译时已知类型)
        Class<String> clazz1 = String.class;
        System.out.println("方式1: " + clazz1.getName());
        
        // 方式2:通过对象.getClass()(运行时已知对象)
        String str = "Hello";
        Class<? extends String> clazz2 = str.getClass();
        System.out.println("方式2: " + clazz2.getName());
        
        // 方式3:通过Class.forName()(全限定类名,动态加载)
        Class<?> clazz3 = Class.forName("java.lang.String");
        System.out.println("方式3: " + clazz3.getName());
        
        // 方式4:通过类加载器(适用于内部类等特殊情况)
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        Class<?> clazz4 = loader.loadClass("java.lang.String");
        System.out.println("方式4: " + clazz4.getName());
        
        // 验证:同一个类的Class对象是唯一的
        System.out.println("clazz1 == clazz2: " + (clazz1 == clazz2)); // true
        System.out.println("clazz2 == clazz3: " + (clazz2 == clazz3)); // true
    }
}

2.2 类信息获取

import java.lang.annotation.*;
import java.lang.reflect.*;

/**
 * 类信息获取示例
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {
    String value();
}

@MyAnnotation("示例类")
class Person implements Comparable<Person>, Cloneable {
    private String name;
    public int age;
    
    public Person() {}
    
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    @Override
    public int compareTo(Person o) {
        return this.age - o.age;
    }
}

public class ClassInfoDemo {
    public static void main(String[] args) {
        Class<Person> clazz = Person.class;
        
        // 基本信息
        System.out.println("=== 基本信息 ===");
        System.out.println("类名: " + clazz.getName());           // 全限定名
        System.out.println("简单类名: " + clazz.getSimpleName()); // 简单名称
        System.out.println("包名: " + clazz.getPackage().getName());
        System.out.println("修饰符: " + Modifier.toString(clazz.getModifiers()));
        
        // 父类
        System.out.println("\n=== 父类 ===");
        Class<? super Person> superClass = clazz.getSuperclass();
        System.out.println("父类: " + superClass.getName());
        
        // 接口
        System.out.println("\n=== 实现的接口 ===");
        Class<?>[] interfaces = clazz.getInterfaces();
        for (Class<?> iface : interfaces) {
            System.out.println("- " + iface.getName());
        }
        
        // 注解
        System.out.println("\n=== 注解 ===");
        if (clazz.isAnnotationPresent(MyAnnotation.class)) {
            MyAnnotation annotation = clazz.getAnnotation(MyAnnotation.class);
            System.out.println("MyAnnotation: " + annotation.value());
        }
        
        // 字段
        System.out.println("\n=== 所有字段(包括私有)===");
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            System.out.println("- " + field.getName() + 
                ": " + field.getType().getSimpleName() +
                " [" + Modifier.toString(field.getModifiers()) + "]");
        }
        
        // 构造器
        System.out.println("\n=== 所有构造器 ===");
        Constructor<?>[] constructors = clazz.getDeclaredConstructors();
        for (Constructor<?> constructor : constructors) {
            System.out.println("- " + constructor.getName() + 
                " 参数: " + Arrays.toString(
                    Arrays.stream(constructor.getParameterTypes())
                          .map(Class::getSimpleName)
                          .toArray(String[]::new)));
        }
        
        // 方法
        System.out.println("\n=== 所有方法(包括私有)===");
        Method[] methods = clazz.getDeclaredMethods();
        for (Method method : methods) {
            System.out.println("- " + method.getName() + 
                " 返回: " + method.getReturnType().getSimpleName() +
                " 参数: " + Arrays.toString(
                    Arrays.stream(method.getParameterTypes())
                          .map(Class::getSimpleName)
                          .toArray(String[]::new)));
        }
    }
}

2.3 字段操作

import java.lang.reflect.Field;

/**
 * 字段操作示例
 */
class User {
    private String username = "default";
    private int age = 18;
    public String email = "test@example.com";
    private static final String VERSION = "1.0";
    
    @Override
    public String toString() {
        return "User{username='" + username + "', age=" + age + 
               ", email='" + email + "'}";
    }
}

public class FieldDemo {
    public static void main(String[] args) throws Exception {
        User user = new User();
        Class<?> clazz = user.getClass();
        
        // 获取公共字段
        System.out.println("=== 公共字段 ===");
        Field[] publicFields = clazz.getFields();
        for (Field field : publicFields) {
            System.out.println(field.getName());
        }
        
        // 获取所有字段(包括私有)
        System.out.println("\n=== 所有字段 ===");
        Field[] allFields = clazz.getDeclaredFields();
        for (Field field : allFields) {
            System.out.println(field.getName() + ": " + field.getType().getSimpleName());
        }
        
        // 读取字段值
        System.out.println("\n=== 读取字段值 ===");
        Field emailField = clazz.getField("email");
        Object emailValue = emailField.get(user);
        System.out.println("email: " + emailValue);
        
        // 修改字段值
        System.out.println("\n=== 修改字段值 ===");
        emailField.set(user, "new@example.com");
        System.out.println("修改后: " + user);
        
        // 操作私有字段
        System.out.println("\n=== 操作私有字段 ===");
        Field usernameField = clazz.getDeclaredField("username");
        usernameField.setAccessible(true); // 打破访问限制
        System.out.println("原始username: " + usernameField.get(user));
        usernameField.set(user, "zhangsan");
        System.out.println("修改后: " + user);
        
        // 操作静态字段
        System.out.println("\n=== 操作静态字段 ===");
        Field versionField = clazz.getDeclaredField("VERSION");
        versionField.setAccessible(true);
        // 静态字段,第一个参数传null
        System.out.println("VERSION: " + versionField.get(null));
        // 注意:final字段在运行时修改会报错或无效
        
        // 字段类型判断
        System.out.println("\n=== 字段类型判断 ===");
        Field ageField = clazz.getDeclaredField("age");
        System.out.println("isPrimitive: " + ageField.getType().isPrimitive());
        System.out.println("isArray: " + ageField.getType().isArray());
    }
}

2.4 方法操作

import java.lang.reflect.Method;
import java.lang.reflect.Parameter;

/**
 * 方法操作示例
 */
class Calculator {
    private int result = 0;
    
    public int add(int a, int b) {
        return a + b;
    }
    
    public int subtract(int a, int b) {
        return a - b;
    }
    
    private void setResult(int result) {
        this.result = result;
    }
    
    public static int multiply(int a, int b) {
        return a * b;
    }
    
    public int sum(int... numbers) {
        int total = 0;
        for (int num : numbers) {
            total += num;
        }
        return total;
    }
    
    public void overloaded(String s) {
        System.out.println("String: " + s);
    }
    
    public void overloaded(int i) {
        System.out.println("int: " + i);
    }
}

public class MethodDemo {
    public static void main(String[] args) throws Exception {
        Calculator calculator = new Calculator();
        Class<?> clazz = calculator.getClass();
        
        // 获取所有公共方法(包括继承的)
        System.out.println("=== 公共方法 ===");
        Method[] publicMethods = clazz.getMethods();
        for (Method method : publicMethods) {
            if (method.getDeclaringClass() == clazz) { // 只看本类定义的
                System.out.println(method.getName());
            }
        }
        
        // 调用普通方法
        System.out.println("\n=== 调用普通方法 ===");
        Method addMethod = clazz.getMethod("add", int.class, int.class);
        Object result = addMethod.invoke(calculator, 10, 20);
        System.out.println("add(10, 20) = " + result);
        
        // 调用私有方法
        System.out.println("\n=== 调用私有方法 ===");
        Method setResultMethod = clazz.getDeclaredMethod("setResult", int.class);
        setResultMethod.setAccessible(true);
        setResultMethod.invoke(calculator, 100);
        
        // 调用静态方法
        System.out.println("\n=== 调用静态方法 ===");
        Method multiplyMethod = clazz.getMethod("multiply", int.class, int.class);
        Object staticResult = multiplyMethod.invoke(null, 5, 6); // 静态方法,对象传null
        System.out.println("multiply(5, 6) = " + staticResult);
        
        // 调用可变参数方法
        System.out.println("\n=== 调用可变参数方法 ===");
        Method sumMethod = clazz.getMethod("sum", int[].class);
        Object sumResult = sumMethod.invoke(calculator, new Object[]{new int[]{1, 2, 3, 4, 5}});
        System.out.println("sum(1,2,3,4,5) = " + sumResult);
        
        // 方法重载处理
        System.out.println("\n=== 方法重载 ===");
        Method overloadedString = clazz.getMethod("overloaded", String.class);
        Method overloadedInt = clazz.getMethod("overloaded", int.class);
        overloadedString.invoke(calculator, "hello");
        overloadedInt.invoke(calculator, 123);
        
        // 方法参数信息(Java 8+)
        System.out.println("\n=== 方法参数信息 ===");
        Parameter[] parameters = addMethod.getParameters();
        for (Parameter param : parameters) {
            System.out.println("参数: " + param.getName() + 
                ", 类型: " + param.getType().getSimpleName());
        }
    }
}

2.5 构造器与对象创建

import java.lang.reflect.Constructor;

/**
 * 构造器操作与对象创建
 */
class Student {
    private String name;
    private int age;
    
    // 无参构造器
    public Student() {
        this.name = "Unknown";
        this.age = 0;
    }
    
    // 有参构造器
    public Student(String name) {
        this.name = name;
        this.age = 18;
    }
    
    // 私有构造器
    private Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    @Override
    public String toString() {
        return "Student{name='" + name + "', age=" + age + "}";
    }
}

public class ConstructorDemo {
    public static void main(String[] args) throws Exception {
        Class<Student> clazz = Student.class;
        
        // 获取所有公共构造器
        System.out.println("=== 公共构造器 ===");
        Constructor<?>[] publicConstructors = clazz.getConstructors();
        for (Constructor<?> constructor : publicConstructors) {
            System.out.println("参数数量: " + constructor.getParameterCount());
        }
        
        // 获取所有构造器(包括私有)
        System.out.println("\n=== 所有构造器 ===");
        Constructor<?>[] allConstructors = clazz.getDeclaredConstructors();
        for (Constructor<?> constructor : allConstructors) {
            System.out.println("参数: " + constructor.getParameterCount() + 
                ", 修饰符: " + Modifier.toString(constructor.getModifiers()));
        }
        
        // 方式1:Class.newInstance()(已废弃,只能调用无参构造器)
        System.out.println("\n=== 创建对象方式1(无参)===");
        Student student1 = clazz.newInstance();
        System.out.println(student1);
        
        // 方式2:Constructor.newInstance()(推荐)
        System.out.println("\n=== 创建对象方式2(有参)===");
        Constructor<Student> constructor1 = clazz.getConstructor(String.class);
        Student student2 = constructor1.newInstance("张三");
        System.out.println(student2);
        
        // 调用私有构造器
        System.out.println("\n=== 调用私有构造器 ===");
        Constructor<Student> privateConstructor = 
            clazz.getDeclaredConstructor(String.class, int.class);
        privateConstructor.setAccessible(true);
        Student student3 = privateConstructor.newInstance("李四", 20);
        System.out.println(student3);
        
        // 获取构造器参数信息
        System.out.println("\n=== 构造器参数信息 ===");
        Constructor<Student> twoArgConstructor = 
            clazz.getDeclaredConstructor(String.class, int.class);
        Class<?>[] paramTypes = twoArgConstructor.getParameterTypes();
        for (Class<?> paramType : paramTypes) {
            System.out.println("参数类型: " + paramType.getSimpleName());
        }
    }
}

2.6 数组操作

import java.lang.reflect.Array;

/**
 * 反射操作数组
 */
public class ArrayDemo {
    public static void main(String[] args) {
        // 创建数组
        System.out.println("=== 创建数组 ===");
        // 创建String[5]
        Object strArray = Array.newInstance(String.class, 5);
        System.out.println("数组类型: " + strArray.getClass().getComponentType());
        System.out.println("数组长度: " + Array.getLength(strArray));
        
        // 设置元素
        Array.set(strArray, 0, "Hello");
        Array.set(strArray, 1, "World");
        
        // 获取元素
        System.out.println("元素[0]: " + Array.get(strArray, 0));
        System.out.println("元素[1]: " + Array.get(strArray, 1));
        
        // 创建多维数组
        System.out.println("\n=== 创建多维数组 ===");
        // 创建int[3][4]
        Object int2DArray = Array.newInstance(int.class, 3, 4);
        System.out.println("类型: " + int2DArray.getClass());
        
        // 操作多维数组
        Object firstRow = Array.get(int2DArray, 0);
        Array.set(firstRow, 0, 100);
        
        // 类型检查
        System.out.println("\n=== 类型检查 ===");
        int[] nums = {1, 2, 3};
        System.out.println("isArray: " + nums.getClass().isArray());
        System.out.println("componentType: " + nums.getClass().getComponentType());
        
        // 转换为数组类型
        String[] strArrayCasted = (String[]) strArray;
        System.out.println("\n转换后: " + java.util.Arrays.toString(strArrayCasted));
    }
}

2.7 动态代理

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

/**
 * 动态代理示例
 */

// 接口
interface UserService {
    void addUser(String name);
    void deleteUser(String name);
    String getUser(String name);
}

// 真实实现
class UserServiceImpl implements UserService {
    @Override
    public void addUser(String name) {
        System.out.println("添加用户: " + name);
    }
    
    @Override
    public void deleteUser(String name) {
        System.out.println("删除用户: " + name);
    }
    
    @Override
    public String getUser(String name) {
        System.out.println("查询用户: " + name);
        return "User-" + name;
    }
}

// 调用处理器
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("[LOG] 调用方法: " + method.getName());
        System.out.println("[LOG] 参数: " + java.util.Arrays.toString(args));
        
        long start = System.currentTimeMillis();
        
        // 调用真实方法
        Object result = method.invoke(target, args);
        
        long end = System.currentTimeMillis();
        
        // 后置处理
        System.out.println("[LOG] 返回值: " + result);
        System.out.println("[LOG] 耗时: " + (end - start) + "ms");
        
        return result;
    }
}

public class ProxyDemo {
    public static void main(String[] args) {
        // 真实对象
        UserService realService = new UserServiceImpl();
        
        // 创建代理对象
        UserService proxyService = (UserService) Proxy.newProxyInstance(
            realService.getClass().getClassLoader(),
            realService.getClass().getInterfaces(),
            new LogInvocationHandler(realService)
        );
        
        // 通过代理调用方法
        System.out.println("=== 调用代理方法 ===");
        proxyService.addUser("张三");
        System.out.println();
        String user = proxyService.getUser("李四");
        System.out.println("\n获取到的用户: " + user);
        
        // 查看代理类信息
        System.out.println("\n=== 代理类信息 ===");
        System.out.println("是否为代理类: " + Proxy.isProxyClass(proxyService.getClass()));
        System.out.println("代理类名: " + proxyService.getClass().getName());
    }
}

三、可运行Java代码示例

完整示例:通用Bean工具类

import java.lang.reflect.*;
import java.util.*;

/**
 * 通用Bean工具类
 */
public class BeanUtils {
    
    /**
     * 复制属性(浅拷贝)
     */
    public static <T> T copyProperties(Object source, Class<T> targetClass) {
        try {
            T target = targetClass.getDeclaredConstructor().newInstance();
            copyProperties(source, target);
            return target;
        } catch (Exception e) {
            throw new RuntimeException("复制属性失败", e);
        }
    }
    
    /**
     * 复制属性到目标对象
     */
    public static void copyProperties(Object source, Object target) {
        Class<?> sourceClass = source.getClass();
        Class<?> targetClass = target.getClass();
        
        for (Field sourceField : sourceClass.getDeclaredFields()) {
            try {
                sourceField.setAccessible(true);
                Object value = sourceField.get(source);
                
                Field targetField;
                try {
                    targetField = targetClass.getDeclaredField(sourceField.getName());
                } catch (NoSuchFieldException e) {
                    continue; // 目标类没有该字段,跳过
                }
                
                if (targetField.getType().isAssignableFrom(sourceField.getType())) {
                    targetField.setAccessible(true);
                    targetField.set(target, value);
                }
            } catch (Exception e) {
                // 忽略单个字段的复制错误
            }
        }
    }
    
    /**
     * 对象转Map
     */
    public static Map<String, Object> toMap(Object obj) {
        Map<String, Object> map = new HashMap<>();
        Class<?> clazz = obj.getClass();
        
        for (Field field : clazz.getDeclaredFields()) {
            try {
                field.setAccessible(true);
                map.put(field.getName(), field.get(obj));
            } catch (Exception e) {
                // 忽略
            }
        }
        
        return map;
    }
    
    /**
     * Map转对象
     */
    public static <T> T fromMap(Map<String, Object> map, Class<T> clazz) {
        try {
            T obj = clazz.getDeclaredConstructor().newInstance();
            
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                try {
                    Field field = clazz.getDeclaredField(entry.getKey());
                    field.setAccessible(true);
                    
                    Object value = entry.getValue();
                    if (value != null && !field.getType().isAssignableFrom(value.getClass())) {
                        // 简单类型转换
                        value = convertValue(value, field.getType());
                    }
                    
                    field.set(obj, value);
                } catch (NoSuchFieldException e) {
                    // 忽略不存在的字段
                }
            }
            
            return obj;
        } catch (Exception e) {
            throw new RuntimeException("Map转对象失败", e);
        }
    }
    
    /**
     * 简单类型转换
     */
    private static Object convertValue(Object value, Class<?> targetType) {
        String strValue = value.toString();
        
        if (targetType == String.class) return strValue;
        if (targetType == int.class || targetType == Integer.class) return Integer.parseInt(strValue);
        if (targetType == long.class || targetType == Long.class) return Long.parseLong(strValue);
        if (targetType == double.class || targetType == Double.class) return Double.parseDouble(strValue);
        if (targetType == boolean.class || targetType == Boolean.class) return Boolean.parseBoolean(strValue);
        
        return value;
    }
    
    /**
     * 获取字段值(支持嵌套路径)
     */
    public static Object getFieldValue(Object obj, String fieldPath) {
        String[] fields = fieldPath.split("\\.");
        Object current = obj;
        
        for (String fieldName : fields) {
            if (current == null) return null;
            
            try {
                Field field = current.getClass().getDeclaredField(fieldName);
                field.setAccessible(true);
                current = field.get(current);
            } catch (Exception e) {
                throw new RuntimeException("获取字段值失败: " + fieldName, e);
            }
        }
        
        return current;
    }
    
    /**
     * 设置字段值(支持嵌套路径)
     */
    public static void setFieldValue(Object obj, String fieldPath, Object value) {
        String[] fields = fieldPath.split("\\.");
        Object current = obj;
        
        // 找到最后一个字段的父对象
        for (int i = 0; i < fields.length - 1; i++) {
            try {
                Field field = current.getClass().getDeclaredField(fields[i]);
                field.setAccessible(true);
                current = field.get(current);
            } catch (Exception e) {
                throw new RuntimeException("获取字段失败: " + fields[i], e);
            }
        }
        
        // 设置最后一个字段的值
        try {
            Field field = current.getClass().getDeclaredField(fields[fields.length - 1]);
            field.setAccessible(true);
            field.set(current, value);
        } catch (Exception e) {
            throw new RuntimeException("设置字段值失败: " + fieldPath, e);
        }
    }
    
    /**
     * 调用getter方法
     */
    public static Object invokeGetter(Object obj, String propertyName) {
        String getterName = "get" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
        try {
            Method getter = obj.getClass().getMethod(getterName);
            return getter.invoke(obj);
        } catch (Exception e) {
            throw new RuntimeException("调用getter失败: " + getterName, e);
        }
    }
    
    /**
     * 调用setter方法
     */
    public static void invokeSetter(Object obj, String propertyName, Object value) {
        String setterName = "set" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
        try {
            Method setter = obj.getClass().getMethod(setterName, value.getClass());
            setter.invoke(obj, value);
        } catch (Exception e) {
            throw new RuntimeException("调用setter失败: " + setterName, e);
        }
    }
}

// === 测试实体类 ===
class Person {
    private String name;
    private int age;
    private Address address;
    
    public Person() {}
    
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    // getter/setter
    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; }
    public Address getAddress() { return address; }
    public void setAddress(Address address) { this.address = address; }
    
    @Override
    public String toString() {
        return "Person{name='" + name + "', age=" + age + ", address=" + address + "}";
    }
}

class Address {
    private String city;
    private String street;
    
    public Address() {}
    
    public Address(String city, String street) {
        this.city = city;
        this.street = street;
    }
    
    public String getCity() { return city; }
    public void setCity(String city) { this.city = city; }
    public String getStreet() { return street; }
    public void setStreet(String street) { this.street = street; }
    
    @Override
    public String toString() {
        return "Address{city='" + city + "', street='" + street + "'}";
    }
}

// === 测试 ===
class BeanUtilsDemo {
    public static void main(String[] args) {
        // 对象转Map
        Person person = new Person("张三", 25);
        person.setAddress(new Address("北京", "朝阳路"));
        
        System.out.println("=== 对象转Map ===");
        Map<String, Object> map = BeanUtils.toMap(person);
        System.out.println(map);
        
        // Map转对象
        System.out.println("\n=== Map转对象 ===");
        Map<String, Object> newMap = new HashMap<>();
        newMap.put("name", "李四");
        newMap.put("age", 30);
        Person newPerson = BeanUtils.fromMap(newMap, Person.class);
        System.out.println(newPerson);
        
        // 嵌套路径获取
        System.out.println("\n=== 嵌套路径获取 ===");
        Object city = BeanUtils.getFieldValue(person, "address.city");
        System.out.println("address.city: " + city);
        
        // getter/setter
        System.out.println("\n=== getter/setter ===");
        String name = (String) BeanUtils.invokeGetter(person, "name");
        System.out.println("getName(): " + name);
        
        BeanUtils.invokeSetter(person, "name", "王五");
        System.out.println("setName后: " + person.getName());
    }
}

完整示例:简易ORM框架

import java.lang.annotation.*;
import java.lang.reflect.*;
import java.sql.*;
import java.util.*;

// === 注解定义 ===

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface Table {
    String name() default "";
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface Id {
    String column() default "";
    boolean autoIncrement() default true;
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface Column {
    String name() default "";
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface Ignore {}

// === ORM核心 ===

class SimpleORM {
    
    /**
     * 插入对象
     */
    public static <T> String generateInsert(T entity) {
        Class<?> clazz = entity.getClass();
        String tableName = getTableName(clazz);
        
        List<String> columns = new ArrayList<>();
        List<String> values = new ArrayList<>();
        
        for (Field field : clazz.getDeclaredFields()) {
            if (field.isAnnotationPresent(Ignore.class)) continue;
            
            field.setAccessible(true);
            Object value;
            try {
                value = field.get(entity);
            } catch (IllegalAccessException e) {
                continue;
            }
            
            // 跳过null值和自增主键
            if (value == null) continue;
            if (field.isAnnotationPresent(Id.class) && 
                field.getAnnotation(Id.class).autoIncrement()) {
                continue;
            }
            
            String columnName = getColumnName(field);
            columns.add(columnName);
            values.add(formatValue(value));
        }
        
        return String.format("INSERT INTO %s (%s) VALUES (%s)",
            tableName,
            String.join(", ", columns),
            String.join(", ", values));
    }
    
    /**
     * 根据ID查询
     */
    public static <T> String generateSelectById(Class<T> clazz, Object id) {
        String tableName = getTableName(clazz);
        Field idField = getIdField(clazz);
        String idColumn = idField.isAnnotationPresent(Id.class) ?
            idField.getAnnotation(Id.class).column() : idField.getName();
        if (idColumn.isEmpty()) idColumn = idField.getName();
        
        return String.format("SELECT * FROM %s WHERE %s = %s",
            tableName, idColumn, formatValue(id));
    }
    
    /**
     * 更新对象
     */
    public static <T> String generateUpdate(T entity) {
        Class<?> clazz = entity.getClass();
        String tableName = getTableName(clazz);
        
        List<String> sets = new ArrayList<>();
        String idCondition = null;
        
        for (Field field : clazz.getDeclaredFields()) {
            if (field.isAnnotationPresent(Ignore.class)) continue;
            
            field.setAccessible(true);
            Object value;
            try {
                value = field.get(entity);
            } catch (IllegalAccessException e) {
                continue;
            }
            
            String columnName = getColumnName(field);
            
            if (field.isAnnotationPresent(Id.class)) {
                idCondition = columnName + " = " + formatValue(value);
            } else if (value != null) {
                sets.add(columnName + " = " + formatValue(value));
            }
        }
        
        if (idCondition == null) {
            throw new RuntimeException("实体类缺少@Id注解字段");
        }
        
        return String.format("UPDATE %s SET %s WHERE %s",
            tableName,
            String.join(", ", sets),
            idCondition);
    }
    
    /**
     * 删除
     */
    public static <T> String generateDelete(Class<T> clazz, Object id) {
        String tableName = getTableName(clazz);
        Field idField = getIdField(clazz);
        String idColumn = getColumnName(idField);
        
        return String.format("DELETE FROM %s WHERE %s = %s",
            tableName, idColumn, formatValue(id));
    }
    
    /**
     * 结果集转对象
     */
    public static <T> T mapResultSet(ResultSet rs, Class<T> clazz) {
        try {
            T obj = clazz.getDeclaredConstructor().newInstance();
            ResultSetMetaData metaData = rs.getMetaData();
            int columnCount = metaData.getColumnCount();
            
            Map<String, Field> fieldMap = new HashMap<>();
            for (Field field : clazz.getDeclaredFields()) {
                field.setAccessible(true);
                fieldMap.put(getColumnName(field).toLowerCase(), field);
                fieldMap.put(field.getName().toLowerCase(), field);
            }
            
            for (int i = 1; i <= columnCount; i++) {
                String columnName = metaData.getColumnLabel(i).toLowerCase();
                Field field = fieldMap.get(columnName);
                
                if (field != null) {
                    Object value = rs.getObject(i);
                    field.set(obj, value);
                }
            }
            
            return obj;
        } catch (Exception e) {
            throw new RuntimeException("映射结果集失败", e);
        }
    }
    
    // === 辅助方法 ===
    
    private static String getTableName(Class<?> clazz) {
        if (clazz.isAnnotationPresent(Table.class)) {
            String name = clazz.getAnnotation(Table.class).name();
            if (!name.isEmpty()) return name;
        }
        // 驼峰转下划线
        return camelToSnake(clazz.getSimpleName());
    }
    
    private static String getColumnName(Field field) {
        if (field.isAnnotationPresent(Id.class)) {
            String name = field.getAnnotation(Id.class).column();
            if (!name.isEmpty()) return name;
        }
        if (field.isAnnotationPresent(Column.class)) {
            String name = field.getAnnotation(Column.class).name();
            if (!name.isEmpty()) return name;
        }
        return camelToSnake(field.getName());
    }
    
    private static Field getIdField(Class<?> clazz) {
        for (Field field : clazz.getDeclaredFields()) {
            if (field.isAnnotationPresent(Id.class)) {
                return field;
            }
        }
        throw new RuntimeException("实体类缺少@Id注解字段");
    }
    
    private static String formatValue(Object value) {
        if (value instanceof String || value instanceof java.util.Date) {
            return "'" + value + "'";
        }
        return value.toString();
    }
    
    private static String camelToSnake(String str) {
        return str.replaceAll("([a-z])([A-Z])", "$1_$2").toLowerCase();
    }
}

// === 测试实体 ===

@Table(name = "t_user")
class User {
    @Id(column = "id")
    private Long id;
    
    @Column(name = "username")
    private String username;
    
    private String password;
    
    private Integer age;
    
    @Ignore
    private String confirmPassword;
    
    // getter/setter省略
    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }
    public String getUsername() { return username; }
    public void setUsername(String username) { this.username = username; }
    public String getPassword() { return password; }
    public void setPassword(String password) { this.password = password; }
    public Integer getAge() { return age; }
    public void setAge(Integer age) { this.age = age; }
    public String getConfirmPassword() { return confirmPassword; }
    public void setConfirmPassword(String confirmPassword) { this.confirmPassword = confirmPassword; }
}

// === 测试 ===
class ORMDemo {
    public static void main(String[] args) {
        // 插入
        User user = new User();
        user.setId(1L);
        user.setUsername("zhangsan");
        user.setPassword("123456");
        user.setAge(25);
        user.setConfirmPassword("123456"); // 会被忽略
        
        System.out.println("=== INSERT ===");
        System.out.println(SimpleORM.generateInsert(user));
        
        System.out.println("\n=== SELECT BY ID ===");
        System.out.println(SimpleORM.generateSelectById(User.class, 1L));
        
        System.out.println("\n=== UPDATE ===");
        user.setAge(26);
        System.out.println(SimpleORM.generateUpdate(user));
        
        System.out.println("\n=== DELETE ===");
        System.out.println(SimpleORM.generateDelete(User.class, 1L));
    }
}

四、实战应用场景

场景1:注解驱动的依赖注入

import java.lang.annotation.*;
import java.lang.reflect.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

// === 注解定义 ===

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface Component {
    String value() default "";
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface Autowired {
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface Qualifier {
    String value();
}

// === 简易IoC容器 ===

class SimpleContainer {
    private static final Map<String, Object> beans = new ConcurrentHashMap<>();
    private static final Map<Class<?>, String> typeToName = new ConcurrentHashMap<>();
    
    /**
     * 注册Bean
     */
    public static void registerBean(String name, Object bean) {
        beans.put(name, bean);
        typeToName.put(bean.getClass(), name);
    }
    
    /**
     * 获取Bean
     */
    @SuppressWarnings("unchecked")
    public static <T> T getBean(String name) {
        return (T) beans.get(name);
    }
    
    public static <T> T getBean(Class<T> clazz) {
        String name = typeToName.get(clazz);
        if (name == null) {
            // 尝试查找实现类
            for (Object bean : beans.values()) {
                if (clazz.isInstance(bean)) {
                    return (T) bean;
                }
            }
        }
        return name != null ? (T) beans.get(name) : null;
    }
    
    /**
     * 扫描并注册组件
     */
    public static void scan(String basePackage) throws Exception {
        // 模拟扫描(实际应扫描类路径)
        Class<?>[] classes = {UserService.class, OrderService.class, UserController.class};
        
        for (Class<?> clazz : classes) {
            if (clazz.isAnnotationPresent(Component.class)) {
                String beanName = clazz.getAnnotation(Component.class).value();
                if (beanName.isEmpty()) {
                    beanName = clazz.getSimpleName();
                    beanName = beanName.substring(0, 1).toLowerCase() + beanName.substring(1);
                }
                
                Object instance = clazz.getDeclaredConstructor().newInstance();
                registerBean(beanName, instance);
            }
        }
        
        // 依赖注入
        for (Object bean : beans.values()) {
            injectDependencies(bean);
        }
    }
    
    /**
     * 依赖注入
     */
    private static void injectDependencies(Object bean) throws Exception {
        Class<?> clazz = bean.getClass();
        
        for (Field field : clazz.getDeclaredFields()) {
            if (field.isAnnotationPresent(Autowired.class)) {
                field.setAccessible(true);
                
                Object dependency;
                if (field.isAnnotationPresent(Qualifier.class)) {
                    String beanName = field.getAnnotation(Qualifier.class).value();
                    dependency = getBean(beanName);
                } else {
                    dependency = getBean(field.getType());
                }
                
                if (dependency != null) {
                    field.set(bean, dependency);
                }
            }
        }
    }
}

// === 示例组件 ===

@Component
interface UserService {
    String getUserName(Long id);
}

@Component("userService")
class UserServiceImpl implements UserService {
    @Override
    public String getUserName(Long id) {
        return "User-" + id;
    }
}

@Component
class OrderService {
    @Autowired
    private UserService userService;
    
    public String getOrderInfo(Long orderId) {
        return "Order-" + orderId + ", User: " + userService.getUserName(1L);
    }
}

@Component
class UserController {
    @Autowired
    @Qualifier("userService")
    private UserService userService;
    
    @Autowired
    private OrderService orderService;
    
    public void showInfo() {
        System.out.println("User: " + userService.getUserName(1L));
        System.out.println("Order: " + orderService.getOrderInfo(100L));
    }
}

// === 测试 ===
class DIDemo {
    public static void main(String[] args) throws Exception {
        SimpleContainer.scan("com.example");
        
        UserController controller = SimpleContainer.getBean(UserController.class);
        controller.showInfo();
    }
}

场景2:动态方法调用器

import java.lang.reflect.*;
import java.util.*;

/**
 * 动态方法调用器
 */
class MethodInvoker {
    
    private final Object target;
    private final Map<String, Method> methodCache = new HashMap<>();
    
    public MethodInvoker(Object target) {
        this.target = target;
        // 缓存所有方法
        for (Method method : target.getClass().getDeclaredMethods()) {
            methodCache.put(method.getName(), method);
        }
    }
    
    /**
     * 调用方法(自动类型转换)
     */
    public Object invoke(String methodName, Object... args) {
        Method method = methodCache.get(methodName);
        if (method == null) {
            throw new IllegalArgumentException("方法不存在: " + methodName);
        }
        
        try {
            // 参数类型转换
            Object[] convertedArgs = convertArgs(method, args);
            method.setAccessible(true);
            return method.invoke(target, convertedArgs);
        } catch (Exception e) {
            throw new RuntimeException("调用方法失败: " + methodName, e);
        }
    }
    
    /**
     * 参数类型转换
     */
    private Object[] convertArgs(Method method, Object[] args) {
        Parameter[] parameters = method.getParameters();
        if (parameters.length == 0 && args == null) return new Object[0];
        if (parameters.length == 0) return new Object[0];
        if (args == null) return new Object[parameters.length];
        
        Object[] result = new Object[parameters.length];
        for (int i = 0; i < parameters.length; i++) {
            if (i < args.length && args[i] != null) {
                result[i] = convertType(args[i], parameters[i].getType());
            }
        }
        return result;
    }
    
    private Object convertType(Object value, Class<?> targetType) {
        if (targetType.isInstance(value)) return value;
        
        String strValue = value.toString();
        
        if (targetType == int.class || targetType == Integer.class) return Integer.parseInt(strValue);
        if (targetType == long.class || targetType == Long.class) return Long.parseLong(strValue);
        if (targetType == double.class || targetType == Double.class) return Double.parseDouble(strValue);
        if (targetType == float.class || targetType == Float.class) return Float.parseFloat(strValue);
        if (targetType == boolean.class || targetType == Boolean.class) return Boolean.parseBoolean(strValue);
        if (targetType == String.class) return strValue;
        
        return value;
    }
    
    /**
     * 获取所有方法名
     */
    public List<String> listMethods() {
        return new ArrayList<>(methodCache.keySet());
    }
    
    /**
     * 获取方法信息
     */
    public String getMethodInfo(String methodName) {
        Method method = methodCache.get(methodName);
        if (method == null) return null;
        
        StringBuilder sb = new StringBuilder();
        sb.append(method.getReturnType().getSimpleName())
          .append(" ").append(method.getName()).append("(");
        
        Parameter[] params = method.getParameters();
        for (int i = 0; i < params.length; i++) {
            if (i > 0) sb.append(", ");
            sb.append(params[i].getType().getSimpleName())
              .append(" ").append(params[i].getName());
        }
        
        sb.append(")");
        return sb.toString();
    }
}

// === 测试 ===
class Calculator {
    public int add(int a, int b) { return a + b; }
    public double divide(double a, double b) { return a / b; }
    public String concat(String a, String b) { return a + b; }
    public void print(String msg) { System.out.println("Message: " + msg); }
}

class MethodInvokerDemo {
    public static void main(String[] args) {
        Calculator calc = new Calculator();
        MethodInvoker invoker = new MethodInvoker(calc);
        
        // 列出方法
        System.out.println("=== 所有方法 ===");
        invoker.listMethods().forEach(m -> 
            System.out.println(invoker.getMethodInfo(m)));
        
        // 动态调用(自动类型转换)
        System.out.println("\n=== 动态调用 ===");
        
        // 字符串参数自动转int
        Object result1 = invoker.invoke("add", "10", "20");
        System.out.println("add('10', '20') = " + result1);
        
        Object result2 = invoker.invoke("divide", 10, 4);
        System.out.println("divide(10, 4) = " + result2);
        
        Object result3 = invoker.invoke("concat", "Hello", "World");
        System.out.println("concat('Hello', 'World') = " + result3);
        
        invoker.invoke("print", "动态调用成功");
    }
}

五、总结与最佳实践

核心要点回顾

功能关键类/方法
获取Class类名.class对象.getClass()Class.forName()
类信息getName()getModifiers()getSuperclass()getInterfaces()
字段操作getField()getDeclaredField()setAccessible()
方法操作getMethod()getDeclaredMethod()invoke()
对象创建newInstance()Constructor.newInstance()
动态代理Proxy.newProxyInstance()InvocationHandler

最佳实践

  1. 缓存反射结果

    // 缓存Method对象,避免重复查找
    private static final Map<String, Method> METHOD_CACHE = new ConcurrentHashMap<>();
    
    public static Method getMethod(Class<?> clazz, String name, Class<?>... paramTypes) {
        String key = clazz.getName() + "#" + name;
        return METHOD_CACHE.computeIfAbsent(key, k -> {
            try {
                return clazz.getMethod(name, paramTypes);
            } catch (NoSuchMethodException e) {
                return null;
            }
        });
    }
    
  2. 使用setAccessible要谨慎

    // 只在必要时使用,访问后考虑恢复
    Field field = clazz.getDeclaredField("name");
    boolean wasAccessible = field.isAccessible();
    field.setAccessible(true);
    try {
        // 操作字段
    } finally {
        field.setAccessible(wasAccessible);
    }
    
  3. 异常处理要完整

    try {
        Method method = clazz.getMethod("doSomething");
        method.invoke(obj);
    } catch (NoSuchMethodException e) {
        // 方法不存在
    } catch (IllegalAccessException e) {
        // 访问权限问题
    } catch (InvocationTargetException e) {
        // 方法执行抛出异常
        Throwable cause = e.getCause(); // 获取真实异常
    }
    
  4. 性能优化建议

    • 缓存反射结果
    • 减少反射调用次数
    • 高频场景考虑代码生成(如ASM、CGLIB)
    • 使用MethodHandle(Java 7+)
  5. 安全注意事项

    • 敏感操作前检查权限
    • 避免暴露内部实现细节
    • 使用SecurityManager控制反射权限

反射 vs MethodHandle

import java.lang.invoke.*;

/**
 * MethodHandle示例(Java 7+,性能更好)
 */
public class MethodHandleDemo {
    public static void main(String[] args) throws Throwable {
        String str = "Hello";
        
        // 反射方式
        Method method = String.class.getMethod("substring", int.class, int.class);
        String result1 = (String) method.invoke(str, 0, 3);
        System.out.println("反射: " + result1);
        
        // MethodHandle方式(更快)
        MethodHandles.Lookup lookup = MethodHandles.lookup();
        MethodType methodType = MethodType.methodType(String.class, int.class, int.class);
        MethodHandle handle = lookup.findVirtual(String.class, "substring", methodType);
        String result2 = (String) handle.invoke(str, 0, 3);
        System.out.println("MethodHandle: " + result2);
    }
}

常见问题

  1. 为什么反射慢?

    • 需要查找元数据
    • 需要检查访问权限
    • 需要创建参数数组
    • JIT优化受限
  2. 如何选择?

    • 框架开发:反射更灵活
    • 高性能场景:MethodHandle或代码生成
    • 简单场景:直接调用

扩展阅读

  • Java反射API文档:java.lang.reflect包
  • MethodHandle:java.lang.invoke包
  • ASM库:字节码操作框架
  • CGLIB:动态代理增强库