Java反射:运行时的类操作
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");
}
}
最佳实践
- 性能考虑:反射有性能开销,避免频繁使用
- 缓存Class对象:提高反射性能
- 使用setAccessible:提高私有成员访问性能
- 异常处理:处理反射相关异常
- 合理使用:优先使用普通方式
总结
反射是Java的高级特性,掌握反射的使用,可以理解框架的设计原理,实现动态代理等功能。