专业编程教程与实战项目分享平台

网站首页 > 技术文章 正文

java 核心技术-12版 卷Ⅰ- 6.5.3 代理类的特性

ins518 2024-11-13 12:28:57 技术文章 14 ℃ 0 评论

原文

6.5.3 代理类的特性

我们已经看到了代理类的具体使用,接下来了解它们的一些特性。需要记住,代理类是在程序运行过程中动态创建的。不过,一旦创建,它们就是常规的类,与虚拟机中的任何其他类没有什么区别。

所有的代理类都扩展 Proxy类。一个代理类只有一个实例字段一一即调用处理器,它在Proxy 超类中定义。完成代理对象任务所需要的任何额外数据都必须存储在调用处理器中。例如,在程序清单6-10给出的程序中,代理Comparable 对象时,TraceHandler 就包装了具体的对象。

所有的代理类都要覆盖 Object类的 toString、equals 和 hashCode 方法。如同所有代理方法样,这些方法只是在调用处理器上调用 invoke。Object类中的其他方法 (如clone 和 getClass)没有重新定义。

没有定义代理类的名字,Oracle 虚拟机中的 Proxy 类会生成以字符串 Proxy 开头的类名。

对于一个特定的类加载器和一组接口,只能有一个代理类。也就是说,如果使用同一个类加载器和接口数组调用两次 newProxyInstance 方法,将得到同一个类的两个对象。也可以利用 getProxyClass 方法获得这个类:

Class proxyClass = Proxy.getProxyClass(null,interfaces);

代理类总是 public和 final。如果代理类实现的所有接口都是 public,这个代理类就不属于任何特定的包;否则,所有非公共的接口都必须属于同一个包,而且代理类也属于这个包。

可以通过调用Proxy类的 isProxyClass 方法检测一个特定的Class 对象是否表示一个代理类。

注释:调用一个目标代理的默认方法会触发调用处理器。要具体调用这个方法,可以使用InvocationHandler接口的静态方法 invokeDefault。例如,下面是一个调用处理器,它会调用默认方法,并把抽象方法传递到另一个目标:


InvocationHandler handler = (proxy, method, args) ->{

	if(method.isDefault()){
    	return InvocationHandler.invokeDefault(proxy, method, args);
    }else{
    	return method.invoke(target , args);  
    }
}


java.lang.reflect.InvocationHandler 1.3

  • Object invoke(Object proxy, Method method , Object[] args) 定义这个方法包含一个动作,你希望只要在代理对象上调用一个方法就完成这个动作。
  • static Object invokeDefault(Object proxy, Method method, Object ... args) jdk16 绕过调用处理器,用给定参数调用代理实例的一个默认方法。

java.lang.reflect.Proxy1.3

  • static Class<?> getProxyClass(ClassLoader loader, Class<?> interfaces) 返回实现指定接口的代理类。
  • static Object newProxyInstance (ClassLoader loader, Class<?>[] interfaces , InvocationHandler handler) 构造实现指定接口的代理类的一个新实例。所有方法都调用给定处理器对象的invoke 方法。
  • static boolean isProxyClass(Class<?> cl) 如果cl 是一个代理类则返回true。

到此为止,Java 程序设计语言的面向对象特性就介绍完毕了。接口、lambda 表达式和内部类是我们经常会遇到的几个概念,不过,克隆、服务加载器和代理等高级技术主要是设计库及构建工具的程序员感兴趣,开发应用程序的程序员对此可能不太关心。接下来可以在第7章学习如何处理程序中的异常情况。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表