反射、代理
1 反射
反射机制可以用于动态操作Java代码,能够知道任意一个类的属性和方法,能够调用任意一个对象的属性和方法
优点:运行时根据类型判断,动态加载类,提高代码灵活度
缺点:性能会慢一些,动态操作类增加了安全隐患
获取Class类
// 通过类获取
Class c = XXX.class;
// 通过对象实例获取
XXX xxx = new XXX();
Class c = xxx.getClass();
// 传入类的路径
Class c = Class.forName("com.xxx.XXX");
// 传入类的路径
Class c = ClassLoader.LoadClass("com.xxx.XXX");
获取属性和方法
class Student {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Main {
public static void main(String[] args) {
Student student = new Student();
Class studentClass = student.getClass();
// 获取所有声明的方法
Method[] methods = studentClass.getDeclaredMethods();
for (Method method : methods) {
System.out.println(method.getName());
}
// 获取类的属性
try {
Field field = studentClass.getDeclaredField("name");
field.setAccessible(true); // 可以操作私有属性,取消安全检查
field.set(student, "123");
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
System.out.println(student.getName());
// 获取类的方法
try {
Method method = studentClass.getDeclaredMethod("setName", String.class);
method.invoke(student, "456");
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
System.out.println(student.getName());
}
}
2 静态代理
代理模式是使用代理对象来代替对真实对象操作,可用于扩展额外的功能
静态代理中,对目标对象每个方法的增强都是手动完成的,被代理对象与代理对象实现相同的接口
静态代理在编译时就将接口、实现类、代理类都变成了实际的class文件
public interface IUserDao {
void save();
}
public class UserDao implements IUserDao {
public void save() {
System.out.println("----已经保存数据!----");
}
}
public class UserDaoProxy implements IUserDao{
//接收保存目标对象
private IUserDao target;
public UserDaoProxy(IUserDao target){
this.target=target;
}
public void save() {
System.out.println("开始事务...");
target.save();//执行目标对象的方法
System.out.println("提交事务...");
}
}
3 动态代理
动态代理在运行时动态生成类字节码,并加载到JVM中
所有的代理类都扩展于Proxy类,一个代理类只有一个实例域——调用处理器
所有的代理类都覆盖了Object类中的方法toString、equals、hashCode
代理类一定是public和final
public class ProxyFactory{
//维护一个目标对象
private Object target;
public ProxyFactory(Object target){
this.target=target;
}
//给目标对象生成代理对象
public Object getProxyInstance(){
return Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("开始事务2");
//执行目标对象方法
Object returnValue = method.invoke(target, args);
System.out.println("提交事务2");
return returnValue;
}
}
);
}
}