← 返回首页

Java反射:运行时的类操作

📂 java ⏱ 2 min 309 words

Java反射:运行时的类操作

概述

反射是Java的高级特性,它允许在运行时动态获取类的信息并操作类的成员。反射是框架设计的基础。

1. 获取Class对象

public class ReflectionDemo {
    public static void main(String[] args) throws Exception {
        Class<?> clazz1 = Class.forName("java.lang.String");
        Class<?> clazz2 = String.class;
        String str = "Hello";
        Class<?> clazz3 = str.getClass();

        System.out.println(clazz1 == clazz2);
        System.out.println(clazz2 == clazz3);
    }
}

2. 动态创建对象

public class CreateObjectDemo {
    public static void main(String[] args) throws Exception {
        Class<?> clazz = Class.forName("java.util.ArrayList");
        Object obj1 = clazz.getDeclaredConstructor().newInstance();

        Class<?> stringClass = Class.forName("java.lang.String");
        Object obj2 = stringClass.getDeclaredConstructor(String.class).newInstance("Hello");

        System.out.println(obj2);
    }
}

3. 访问字段

public class User {
    private String name;
    private int age;
}

public class FieldAccessDemo {
    public static void main(String[] args) throws Exception {
        Class<?> clazz = User.class;
        User user = (User) clazz.getDeclaredConstructor().newInstance();

        Field nameField = clazz.getDeclaredField("name");
        nameField.setAccessible(true);
        nameField.set(user, "John");

        String name = (String) nameField.get(user);
        System.out.println(name);
    }
}

4. 调用方法

public class MethodInvokeDemo {
    public static void main(String[] args) throws Exception {
        Class<?> clazz = Class.forName("java.lang.Math");
        Method absMethod = clazz.getMethod("abs", int.class);
        Object result = absMethod.invoke(null, -100);
        System.out.println(result);

        String str = "Hello";
        Method lengthMethod = str.getClass().getMethod("length");
        int length = (int) lengthMethod.invoke(str);
        System.out.println(length);
    }
}

5. 动态代理

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

interface UserService {
    void save(String name);
    void delete(Long id);
}

class UserServiceImpl implements UserService {
    @Override
    public void save(String name) {
        System.out.println("保存用户: " + name);
    }
    @Override
    public void delete(Long id) {
        System.out.println("删除用户: " + id);
    }
}

class ServiceProxy implements InvocationHandler {
    private Object target;
    public ServiceProxy(Object target) { this.target = target; }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("方法执行前: " + method.getName());
        Object result = method.invoke(target, args);
        System.out.println("方法执行后: " + method.getName());
        return result;
    }
}

public class ProxyDemo {
    public static void main(String[] args) {
        UserService target = new UserServiceImpl();
        ServiceProxy handler = new ServiceProxy(target);
        UserService proxy = (UserService) Proxy.newProxyInstance(
            target.getClass().getClassLoader(),
            target.getClass().getInterfaces(),
            handler
        );
        proxy.save("John");
    }
}

最佳实践

  1. 性能考虑:反射有性能开销,避免频繁使用
  2. 缓存Class对象:提高反射性能
  3. 使用setAccessible:提高私有成员访问性能
  4. 异常处理:处理反射相关异常
  5. 合理使用:优先使用普通方式

总结

反射是Java的高级特性,掌握反射的使用,可以理解框架的设计原理,实现动态代理等功能。