反射
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对象或使用代码生成工具。