|
|||||||||
| Home >> All >> java >> lang >> [ reflect overview ] | PREV CLASS NEXT CLASS | ||||||||
SUMMARY: JAVADOC | SOURCE | DOWNLOAD | NESTED | FIELD | CONSTR | METHOD |
DETAIL: FIELD | CONSTR | METHOD | ||||||||
java.lang.reflect
Class Proxy

java.lang.Objectjava.lang.reflect.Proxy
- All Implemented Interfaces:
- java.io.Serializable
- public class Proxy
- extends java.lang.Object
- implements java.io.Serializable
- extends java.lang.Object
This class allows you to dynamically create an instance of any (or even multiple) interfaces by reflection, and decide at runtime how that instance will behave by giving it an appropriate InvocationHandler. Proxy classes serialize specially, so that the proxy object can be reused between VMs, without requiring a persistent copy of the generated class code.
Creation
To create a proxy for some interface 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);
Dynamic Proxy Classes
A dynamic proxy class is created at runtime, and has the following properties:- The class is
publicandfinal, and is neitherabstractnor an inner class. - The class has no canonical name (there is no formula you can use to determine or generate its name), but begins with the sequence "$Proxy". Abuse this knowledge at your own peril. (For now, '$' in user identifiers is legal, but it may not be that way forever. You weren't using '$' in your identifiers, were you?)
- The class extends Proxy, and explicitly implements all the interfaces specified at creation, in order (this is important for determining how method invocation is resolved). Note that a proxy class implements java.io.Serializable, at least implicitly, since Proxy does, but true serial behavior depends on using a serializable invocation handler as well.
- If at least one interface is non-public, the proxy class will be in the same package. Otherwise, the package is unspecified. This will work even if the package is sealed from user-generated classes, because Proxy classes are generated by a trusted source. Meanwhile, the proxy class belongs to the classloader you designated.
- Reflection works as expected: Class.getInterfaces()>
Class.getInterfaces()55 and Class.getMethods()>Class.getMethods()55 work as they do on normal classes. - The method
isProxyClass(Class)55 will distinguish between true proxy classes and user extensions of this class. It only returns true for classes created bygetProxyClass(java.lang.ClassLoader, java.lang.Class[])55 . - The java.security.ProtectionDomain of a proxy class is the same as for bootstrap classes, such as Object or Proxy, since it is created by a trusted source. This protection domain will typically be granted java.security.AllPermission. But this is not a security risk, since there are adequate permissions on reflection, which is the only way to create an instance of the proxy class.
- The proxy class contains a single constructor, which takes as
its only argument an InvocationHandler. The method
newProxyInstance(ClassLoader, Class[], InvocationHandler)55 is shorthand to do the necessary reflection.
Proxy Instances
A proxy instance is an instance of a proxy class. It has the following properties, many of which follow from the properties of a proxy class listed above:- For a proxy class with Foo listed as one of its interfaces, the
expression
proxy instanceof Foowill return true, and the expression(Foo) proxywill succeed without a java.lang.ClassCastException. - Each proxy instance has an invocation handler, which can be
accessed by
getInvocationHandler(Object)55 . Any call to an interface method, including Object.hashCode()>Object.hashCode()55 , Object.equals(Object)>Object.equals(Object)55 , or Object.toString()>Object.toString()55 , but excluding the public final methods of Object, will be encoded and passed to theInvocationHandler.invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])55 method of this handler.
Inheritance Issues
A proxy class may inherit a method from more than one interface. The order in which interfaces are listed matters, because it determines which reflected Method object will be passed to the invocation handler. This means that the dynamically generated class cannot determine through which interface a method is being invoked.In short, if a method is declared in Object (namely, hashCode, equals, or toString), then Object will be used; otherwise, the leftmost interface that inherits or declares a method will be used, even if it has a more permissive throws clause than what the proxy class is allowed. Thus, in the invocation handler, it is not always safe to assume that every class listed in the throws clause of the passed Method object can safely be thrown; fortunately, the Proxy instance is robust enough to wrap all illegal checked exceptions in UndeclaredThrowableException.
- Since:
- 1.3
| Nested Class Summary | |
private static class |
Proxy.ClassFactory
Does all the work of building a class. |
(package private) static class |
Proxy.ProxyData
A flat representation of all data needed to generate bytecode/instantiate a proxy class. |
private static class |
Proxy.ProxySignature
Helper class which allows hashing of a method name and signature without worrying about return type, declaring class, or throws clause, and which reduces the maximally common throws clause between two methods |
private static class |
Proxy.ProxyType
Helper class for mapping unique ClassLoader and interface combinations to proxy classes. |
| Field Summary | |
protected InvocationHandler |
h
The invocation handler for this proxy instance. |
private static java.util.Map |
proxyClasses
Map of ProxyType to proxy class. |
private static long |
serialVersionUID
Compatible with JDK 1.3+. |
| Constructor Summary | |
protected |
Proxy(InvocationHandler handler)
Constructs a new Proxy from a subclass (usually a proxy class), with the specified invocation handler. |
| Method Summary | |
static InvocationHandler |
getInvocationHandler(java.lang.Object proxy)
Returns the invocation handler for the given proxy instance. |
static java.lang.Class |
getProxyClass(java.lang.ClassLoader loader,
java.lang.Class[] interfaces)
Returns the proxy java.lang.Class for the given ClassLoader and array of interfaces, dynamically generating it if necessary. |
static boolean |
isProxyClass(java.lang.Class clazz)
Returns true if and only if the Class object is a dynamically created proxy class (created by getProxyClass or by the
syntactic sugar of newProxyInstance). |
static java.lang.Object |
newProxyInstance(java.lang.ClassLoader loader,
java.lang.Class[] interfaces,
InvocationHandler handler)
Combines several methods into one. |
| Methods inherited from class java.lang.Object |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
| Field Detail |
serialVersionUID
private static final long serialVersionUID
- Compatible with JDK 1.3+.
- See Also:
- Constant Field Values
proxyClasses
private static final java.util.Map proxyClasses
- Map of ProxyType to proxy class.
h
protected InvocationHandler h
- The invocation handler for this proxy instance. For Proxy, this
field is unused, but it appears here in order to be serialized in all
proxy classes.
NOTE: This implementation is more secure for proxy classes
than what Sun specifies. Sun does not require h to be immutable, but
this means you could change h after the fact by reflection. However,
by making h immutable, we may break non-proxy classes which extend
Proxy.
| Constructor Detail |
Proxy
protected Proxy(InvocationHandler handler)
- Constructs a new Proxy from a subclass (usually a proxy class),
with the specified invocation handler.
NOTE: This throws a NullPointerException if you attempt
to create a proxy instance with a null handler using reflection.
This behavior is not yet specified by Sun; see Sun Bug 4487672.
| Method Detail |
getProxyClass
public static java.lang.Class getProxyClass(java.lang.ClassLoader loader, java.lang.Class[] interfaces)
- Returns the proxy java.lang.Class for the given ClassLoader and array
of interfaces, dynamically generating it if necessary.
There are several restrictions on this method, the violation of which will result in an IllegalArgumentException or NullPointerException:
- All objects in `interfaces' must represent distinct interfaces. Classes, primitive types, null, and duplicates are forbidden.
- The interfaces must be visible in the specified ClassLoader.
In other words, for each interface i:
Class.forName(i.getName(), false, loader) == imust be true. - All non-public interfaces (if any) must reside in the same package, or the proxy class would be non-instantiable. If there are no non-public interfaces, the package of the proxy class is unspecified.
- All interfaces must be compatible - if two declare a method with the same name and parameters, the return type must be the same and the throws clause of the proxy class will be the maximal subset of subclasses of the throws clauses for each method that is overridden.
- VM constraints limit the number of interfaces a proxy class may directly implement (however, the indirect inheritance of java.io.Serializable does not count against this limit). Even though most VMs can theoretically have 65535 superinterfaces for a class, the actual limit is smaller because a class's constant pool is limited to 65535 entries, and not all entries can be interfaces.
Note that different orders of interfaces produce distinct classes.
newProxyInstance
public static java.lang.Object newProxyInstance(java.lang.ClassLoader loader, java.lang.Class[] interfaces, InvocationHandler handler)
- Combines several methods into one. This is equivalent to:
Proxy.getProxyClass(loader, interfaces) .getConstructor(new Class[] {InvocationHandler.class}) .newInstance(new Object[] {handler});except that it will not fail with the normal problems caused by reflection. It can still fail for the same reasons documented in getProxyClass, or if handler is null.
isProxyClass
public static boolean isProxyClass(java.lang.Class clazz)
- Returns true if and only if the Class object is a dynamically created
proxy class (created by
getProxyClassor by the syntactic sugar ofnewProxyInstance).This check is secure (in other words, it is not simply
clazz.getSuperclass() == Proxy.class), it will not be spoofed by non-proxy classes that extend Proxy.
getInvocationHandler
public static InvocationHandler getInvocationHandler(java.lang.Object proxy)
- Returns the invocation handler for the given proxy instance.
NOTE: We guarantee a non-null result if successful, but Sun allows the creation of a proxy instance with a null handler. See the comments for
Proxy(InvocationHandler)55 .
|
|||||||||
| Home >> All >> java >> lang >> [ reflect overview ] | PREV CLASS NEXT CLASS | ||||||||
SUMMARY: JAVADOC | SOURCE | DOWNLOAD | NESTED | FIELD | CONSTR | METHOD |
DETAIL: FIELD | CONSTR | METHOD | ||||||||
JAVADOC
java.lang.reflect.Proxy