Most visited

Recently visited

Added in API level 1

Proxy

public class Proxy
extends Object implements Serializable

java.lang.Object
   ↳ java.lang.reflect.Proxy


Proxy提供了创建动态代理类和实例的静态方法,它也是由这些方法创建的所有动态代理类的超类。

为某个接口创建代理 Foo

     InvocationHandler handler = new MyInvocationHandler(...);
     Class proxyClass = Proxy.getProxyClass(
         Foo.class.getClassLoader(), new Class[] { Foo.class });
     Foo f = (Foo) proxyClass.
         getConstructor(new Class[] { InvocationHandler.class }).
         newInstance(new Object[] { handler });
 
or more simply:
     Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
                                          new Class[] { Foo.class },
                                          handler);
 

动态代理类 (以下简称为代理类 )是一个类,它实现了创建类时在运行时指定的接口列表,其行为如下所述。 代理接口是由代理类实现的接口。 代理实例是代理类的实例。 每个代理实例都有一个关联的调用处理程序对象,它实现了接口InvocationHandler 通过其代理接口之一上的代理实例的方法调用将被分派到invoke实例的调用处理程序的方法,并传递代理实例,一个java.lang.reflect.Method对象识别的方法被调用,和类型的数组Object包含参数。 调用处理程序适当地处理编码的方法调用,并且返回的结果将作为代理实例上方法调用的结果返回。

代理类具有以下属性:

代理实例具有以下属性:

Methods Duplicated in Multiple Proxy Interfaces

当代理类的两个或多个接口包含具有相同名称和参数签名的方法时,代理类的接口顺序变得很重要。 当这样的重复的方法是在一个代理实例调用时, 方法传递给调用处理程序对象将不一定是其声明类是从该代理的方法是通过调用接口的引用类型分配的一个。 存在此限制是因为生成的代理类中的相应方法实现无法确定通过哪个接口调用它。 因此,当重复的方法是在代理实例调用时, 方法对象为接口的代理类的列表包含方法(直接或继承通过超接口)中最重要的接口中的方法传递给调用处理程序的invoke方法,而与方法调用发生的引用类型无关。

如果代理接口包含具有相同的名称和参数签名的方法hashCodeequals ,或toString的方法java.lang.Object ,当这种方法在代理实例调用时, 方法传递到调用处理程序对象将java.lang.Object作为其宣布课程。 换句话说, java.lang.Object的公共非最终方法在逻辑上位于所有代理接口之前,以确定哪个方法对象传递给调用处理程序。

另请注意,将重复方法分派给调用处理程序时, invoke方法可能只会引发已检查的异常类型,这些异常类型可分配给该方法的throws子句中的一个异常类型, throws在可调用的所有代理接口中通过。 如果invoke方法抛出一个检查的异常,该异常不可分配给该方法声明的任何异常类型,并且该异常类型可以通过其中一个代理接口进行调用,则未UndeclaredThrowableException将由代理实例上的调用引发。 此限制意味着,并非所有通过调用返回的异常类型的getExceptionTypes的上方法传递给对象invoke方法一定可以成功地抛出invoke方法。

也可以看看:

Summary

Fields

protected InvocationHandler h

此代理实例的调用处理程序。

Protected constructors

Proxy(InvocationHandler h)

从其子类(通常为动态代理类)构造一个新的 Proxy实例,并为其调用处理程序指定一个值。

Public methods

static InvocationHandler getInvocationHandler(Object proxy)

返回指定代理实例的调用处理程序。

static Class<?> getProxyClass(ClassLoader loader, Class...<?> interfaces)

给定类加载器和一组接口,返回代理类的 java.lang.Class对象。

static boolean isProxyClass(Class<?> cl)

当且仅当使用 getProxyClass方法或 newProxyInstance方法将指定的类动态生成为代理类时才返回true。

static Object newProxyInstance(ClassLoader loader, Class[]<?> interfaces, InvocationHandler h)

返回指定接口的代理类实例,该接口将方法调用分派给指定的调用处理程序。

Inherited methods

From class java.lang.Object

Fields

h

Added in API level 1
InvocationHandler h

此代理实例的调用处理程序。

Protected constructors

Proxy

Added in API level 1
Proxy (InvocationHandler h)

从其子类(通常是动态代理类)构造一个新的 Proxy实例,并为其调用处理程序指定一个值。

Parameters
h InvocationHandler: the invocation handler for this proxy instance

Public methods

getInvocationHandler

Added in API level 1
InvocationHandler getInvocationHandler (Object proxy)

返回指定代理实例的调用处理程序。

Parameters
proxy Object: the proxy instance to return the invocation handler for
Returns
InvocationHandler the invocation handler for the proxy instance
Throws
IllegalArgumentException if the argument is not a proxy instance

getProxyClass

Added in API level 1
Class<?> getProxyClass (ClassLoader loader, 
                Class...<?> interfaces)

给定一个类加载器和一组接口,返回代理类的java.lang.Class对象。 代理类将由指定的类加载器定义,并将实现所有提供的接口。 如果类加载器已经定义了相同接口排列的代理类,则将返回现有的代理类; 否则,这些接口的代理类将被动态生成并由类加载器定义。

对可能传递给 Proxy.getProxyClass的参数有几个限制:

  • All of the Class objects in the interfaces array must represent interfaces, not classes or primitive types.
  • No two elements in the interfaces array may refer to identical Class objects.
  • All of the interface types must be visible by name through the specified class loader. In other words, for class loader cl and every interface i, the following expression must be true:
         Class.forName(i.getName(), false, cl) == i
     
  • All non-public interfaces must be in the same package; otherwise, it would not be possible for the proxy class to implement all of the interfaces, regardless of what package it is defined in.
  • For any set of member methods of the specified interfaces that have the same signature:
    • If the return type of any of the methods is a primitive type or void, then all of the methods must have that same return type.
    • Otherwise, one of the methods must have a return type that is assignable to all of the return types of the rest of the methods.
  • The resulting proxy class must not exceed any limits imposed on classes by the virtual machine. For example, the VM may limit the number of interfaces that a class may implement to 65535; in that case, the size of the interfaces array must not exceed 65535.

如果违反了这些限制,则Proxy.getProxyClass将抛出IllegalArgumentException 如果interfaces数组参数或其任何元素为null ,则会引发NullPointerException

请注意,指定的代理接口的顺序非常重要:对具有相同接口组合但具有不同顺序的代理类的两个请求将导致两个不同的代理类。

Parameters
loader ClassLoader: the class loader to define the proxy class
interfaces Class: the list of interfaces for the proxy class to implement
Returns
Class<?> a proxy class that is defined in the specified class loader and that implements the specified interfaces
Throws
IllegalArgumentException if any of the restrictions on the parameters that may be passed to getProxyClass are violated
NullPointerException if the interfaces array argument or any of its elements are null

isProxyClass

Added in API level 1
boolean isProxyClass (Class<?> cl)

当且仅当使用 getProxyClass方法或 newProxyInstance方法将指定的类动态生成为代理类时才返回true。

这种方法的可靠性对于使用它来做出安全决策的能力很重要,因此它的实现不应该仅仅测试有问题的类是否扩展了 Proxy

Parameters
cl Class: the class to test
Returns
boolean true if the class is a proxy class and false otherwise
Throws
NullPointerException if cl is null

newProxyInstance

Added in API level 1
Object newProxyInstance (ClassLoader loader, 
                Class[]<?> interfaces, 
                InvocationHandler h)

返回指定接口的代理类实例,该接口将方法调用分派给指定的调用处理程序。 这种方法相当于:

     Proxy.getProxyClass(loader, interfaces).
         getConstructor(new Class[] { InvocationHandler.class }).
         newInstance(new Object[] { handler });
 

Proxy.newProxyInstance抛出 IllegalArgumentException为同样的原因 Proxy.getProxyClass一样。

Parameters
loader ClassLoader: the class loader to define the proxy class
interfaces Class: the list of interfaces for the proxy class to implement
h InvocationHandler: the invocation handler to dispatch method invocations to
Returns
Object a proxy instance with the specified invocation handler of a proxy class that is defined by the specified class loader and that implements the specified interfaces
Throws
IllegalArgumentException if any of the restrictions on the parameters that may be passed to getProxyClass are violated
NullPointerException if the interfaces array argument or any of its elements are null, or if the invocation handler, h, is null

Hooray!