Java基础(三)——反射、代理

反射、代理

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;
                    }
                }
        );
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值