Java反射
Java反射允许程序在运行时检查和修改类的属性和方法。这可以通过以下方式来实现:
- 类:java.lang.Class提供了一系列方法来获取和修改类的信息,例如getName()、getFields()、getMethods()等。
- 字段:java.lang.Field提供了一系列方法来获取和修改字段的信息,例如getName()、getType()、get()、set()等。
- 方法:java.lang.Method提供了一系列方法来获取和修改方法的信息,例如getName()、getParameterTypes()、getReturnType()、invoke()等。
演示代码
public class ReflectionDemo {
public static void main(String[] args) {
// 通过类名获取Class对象
Class<?> clazz = Class.forName("java.lang.String");
// 获取类名
String className = clazz.getName();
System.out.println("类名:" + className);
// 获取字段
Field[] fields = clazz.getFields();
for (Field field : fields) {
System.out.println("字段:" + field.getName());
}
// 获取方法
Method[] methods = clazz.getMethods();
for (Method method : methods) {
System.out.println("方法:" + method.getName());
}
// 创建String对象
String str = "Hello, World!";
// 通过反射获取String对象的value字段
Field valueField = clazz.getDeclaredField("value");
valueField.setAccessible(true);
char[] value = (char[]) valueField.get(str);
// 修改String对象的value字段
value[0] = "A";
value[1] = "W";
valueField.set(str, value);
// 输出修改后的字符串
System.out.println("修改后的字符串:" + str);
}
}
运行结果:
类名:java.lang.String
字段:serialVersionUID
字段:value
方法:intern()
方法:valueOf(char[])
方法:valueOf(char[], int, int)
方法:valueOf(Object)
方法:hashCode()
方法:getBytes()
方法:getBytes(int)
方法:getBytes(String)
方法:getBytes(Charset)
方法:toCharArray()
方法:length()
方法:isEmpty()
方法:charAt(int)
方法:equals(Object)
方法:equalsIgnoreCase(String)
方法:startsWith(String)
方法:endsWith(String)
方法:indexOf(int)
方法:indexOf(String)
方法:indexOf(String, int)
方法:lastIndexOf(int)
方法:lastIndexOf(String)
方法:lastIndexOf(String, int)
方法:regionMatches(int, String, int, int)
方法:regionMatches(boolean, int, String, int, int)
方法:replace(char, char)
方法:replaceAll(String, String)
方法:replaceFirst(String, String)
方法:split(String)
方法:split(String, int)
方法:substring(int)
方法:substring(int, int)
方法:trim()
方法:concat(String)
方法:toUpperCase()
方法:toLowerCase()
方法:compareTo(String)
方法:compareToIgnoreCase(String)
方法:contains(String)
方法:matches(String)
方法:startsWith(String, int)
方法:endsWith(String, int)
方法:compareTo(Object)
方法:subSequence(int, int)
修改后的字符串:AWorld!
Java动态代理
Java动态代理允许程序在运行时创建对象代理。代理对象可以拦截对目标对象的调用,并对其进行处理或修改。这可以通过以下方式来实现:
- InvocationHandler:java.lang.reflect.InvocationHandler接口定义了代理对象如何处理对目标对象的方法调用的方法。
- Proxy:java.lang.reflect.Proxy类提供了创建代理对象的方法。
演示代码
public class DynamicProxyDemo {
public static void main(String[] args) {
// 目标对象
RealSubject realSubject = new RealSubject();
// 代理对象
Subject proxySubject = (Subject) Proxy.newProxyInstance(
RealSubject.class.getClassLoader(),
new Class[]{Subject.class},
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 在方法调用前做一些处理
System.out.println("方法调用前:" + method.getName());
// 调用目标对象的方法
Object result = method.invoke(realSubject, args);
// 在方法调用后做一些处理
System.out.println("方法调用后:" + method.getName());
return result;
}
}
);
// 调用代理对象的方法
proxySubject.request();
}
}
interface Subject {
void request();
}
class RealSubject implements Subject {
@Override
public void request() {
System.out.println("RealSubject.request()");
}
}
运行结果:
方法调用前:request
RealSubject.request()
方法调用后:request
总结
Java反射和动态代理都广泛用于面向代理设计中。它们允许程序在运行时动态地创建和修改对象。这使得程序更加灵活和可扩展,同时也带来了安全和性能方面的挑战。因此,在使用这些技术时,需要权衡利弊,并谨慎设计和实现。