Proxy
provides static methods for creating dynamic proxy
classes and instances, and it is also the superclass of all
dynamic proxy classes created by those methods.
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);
A dynamic proxy class (simply referred to as a proxy
class below) is a class that implements a list of interfaces
specified at runtime when the class is created, with behavior as
described below.
A proxy interface is such an interface that is implemented
by a proxy class.
A proxy instance is an instance of a proxy class.
Each proxy instance has an associated invocation handler
object, which implements the interface InvocationHandler
.
A method invocation on a proxy instance through one of its proxy
interfaces will be dispatched to the invoke
method of the instance's invocation handler, passing the proxy
instance, a java.lang.reflect.Method
object identifying
the method that was invoked, and an array of type Object
containing the arguments. The invocation handler processes the
encoded method invocation as appropriate and the result that it
returns will be returned as the result of the method invocation on
the proxy instance.
A proxy class has the following properties:
"$Proxy"
should be, however, reserved for proxy classes.
java.lang.reflect.Proxy
.
getInterfaces
on its
Class
object will return an array containing the same
list of interfaces (in the order specified at its creation), invoking
getMethods
on its Class
object will return
an array of Method
objects that include all of the
methods in those interfaces, and invoking getMethod
will
find methods in the proxy interfaces as would be expected.
Proxy.getProxyClass
or the class of an object returned by
Proxy.newProxyInstance
-- and false otherwise.
java.security.ProtectionDomain
of a proxy class
is the same as that of system classes loaded by the bootstrap class
loader, such as java.lang.Object
, because the code for a
proxy class is generated by trusted system code. This protection
domain will typically be granted
java.security.AllPermission
.
A proxy instance has the following properties:
proxy
and one of the
interfaces implemented by its proxy class Foo
, the
following expression will return true:
proxy instanceof Foo
and the following cast operation will succeed (rather than throwing
a ClassCastException
):
(Foo) proxy
hashCode
,
equals
, or toString
methods declared in
java.lang.Object
on a proxy instance will be encoded and
dispatched to the invocation handler's invoke
method in
the same manner as interface method invocations are encoded and
dispatched, as described above. The declaring class of the
Method
object passed to invoke
will be
java.lang.Object
. Other public methods of a proxy
instance inherited from java.lang.Object
are not
overridden by a proxy class, so invocations of those methods behave
like they do for instances of java.lang.Object
.
When two or more interfaces of a proxy class contain a method with
the same name and parameter signature, the order of the proxy class's
interfaces becomes significant. When such a duplicate method
is invoked on a proxy instance, the Method
object passed
to the invocation handler will not necessarily be the one whose
declaring class is assignable from the reference type of the interface
that the proxy's method was invoked through. This limitation exists
because the corresponding method implementation in the generated proxy
class cannot determine which interface it was invoked through.
Therefore, when a duplicate method is invoked on a proxy instance,
the Method
object for the method in the foremost interface
that contains the method (either directly or inherited through a
superinterface) in the proxy class's list of interfaces is passed to
the invocation handler's invoke
method, regardless of the
reference type through which the method invocation occurred.
If a proxy interface contains a method with the same name and
parameter signature as the hashCode
, equals
,
or toString
methods of java.lang.Object
,
when such a method is invoked on a proxy instance, the
Method
object passed to the invocation handler will have
java.lang.Object
as its declaring class. In other words,
the public, non-final methods of java.lang.Object
logically precede all of the proxy interfaces for the determination of
which Method
object to pass to the invocation handler.
Note also that when a duplicate method is dispatched to an
invocation handler, the invoke
method may only throw
checked exception types that are assignable to one of the exception
types in the throws
clause of the method in all of
the proxy interfaces that it can be invoked through. If the
invoke
method throws a checked exception that is not
assignable to any of the exception types declared by the method in one
of the proxy interfaces that it can be invoked through, then an
unchecked UndeclaredThrowableException
will be thrown by
the invocation on the proxy instance. This restriction means that not
all of the exception types returned by invoking
getExceptionTypes
on the Method
object
passed to the invoke
method can necessarily be thrown
successfully by the invoke
method.
The equals
method implements an equivalence relation
on non-null object references:
x
, x.equals(x)
should return
true
.
x
and y
, x.equals(y)
should return true
if and only if
y.equals(x)
returns true
.
x
, y
, and z
, if
x.equals(y)
returns true
and
y.equals(z)
returns true
, then
x.equals(z)
should return true
.
x
and y
, multiple invocations of
x.equals(y) consistently return true
or consistently return false
, provided no
information used in equals
comparisons on the
objects is modified.
x
,
x.equals(null)
should return false
.
The equals method for class Object
implements
the most discriminating possible equivalence relation on objects;
that is, for any non-null reference values x
and
y
, this method returns true
if and only
if x
and y
refer to the same object
(x == y
has the value true
).
Note that it is generally necessary to override the hashCode method whenever this method is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes.
java.lang.Class
object for a proxy class
given a class loader and an array of interfaces. The proxy class
will be defined by the specified class loader and will implement
all of the supplied interfaces. If a proxy class for the same
permutation of interfaces has already been defined by the class
loader, then the existing proxy class will be returned; otherwise,
a proxy class for those interfaces will be generated dynamically
and defined by the class loader.
There are several restrictions on the parameters that may be
passed to Proxy.getProxyClass
:
Class
objects in the
interfaces
array must represent interfaces, not
classes or primitive types.
interfaces
array may
refer to identical Class
objects.
cl
and every interface i
, the following
expression must be true:
Class.forName(i.getName(), false, cl) == i
interfaces
array must not
exceed 65535.
If any of these restrictions are violated,
Proxy.getProxyClass
will throw an
IllegalArgumentException
. If the interfaces
array argument or any of its elements are null
, a
NullPointerException
will be thrown.
Note that the order of the specified proxy interfaces is significant: two requests for a proxy class with the same combination of interfaces but in a different order will result in two distinct proxy classes.
java.util.Hashtable
.
The general contract of hashCode
is:
hashCode
method on each of
the two objects must produce the same integer result.
As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects. (This is typically implemented by converting the internal address of the object into an integer, but this implementation technique is not required by the JavaTM programming language.)
getProxyClass
method or the newProxyInstance
method.
The reliability of this method is important for the ability
to use it to make security decisions, so its implementation should
not just test if the class in question extends Proxy
.
Proxy.getProxyClass(loader, interfaces). getConstructor(new Class[] { InvocationHandler.class }). newInstance(new Object[] { handler });
Proxy.newProxyInstance
throws
IllegalArgumentException
for the same reasons that
Proxy.getProxyClass
does.
wait
methods.
The awakened thread will not be able to proceed until the current thread relinquishes the lock on this object. The awakened thread will compete in the usual manner with any other threads that might be actively competing to synchronize on this object; for example, the awakened thread enjoys no reliable privilege or disadvantage in being the next thread to lock this object.
This method should only be called by a thread that is the owner of this object's monitor. A thread becomes the owner of the object's monitor in one of three ways:
synchronized
statement
that synchronizes on the object.
Class,
by executing a
synchronized static method of that class.
Only one thread at a time can own an object's monitor.
wait
methods.
The awakened threads will not be able to proceed until the current thread relinquishes the lock on this object. The awakened threads will compete in the usual manner with any other threads that might be actively competing to synchronize on this object; for example, the awakened threads enjoy no reliable privilege or disadvantage in being the next thread to lock this object.
This method should only be called by a thread that is the owner
of this object's monitor. See the notify
method for a
description of the ways in which a thread can become the owner of
a monitor.
toString
method returns a string that
"textually represents" this object. The result should
be a concise but informative representation that is easy for a
person to read.
It is recommended that all subclasses override this method.
The toString
method for class Object
returns a string consisting of the name of the class of which the
object is an instance, the at-sign character `@
', and
the unsigned hexadecimal representation of the hash code of the
object. In other words, this method returns a string equal to the
value of:
getClass().getName() + '@' + Integer.toHexString(hashCode())
The current thread must own this object's monitor. The thread
releases ownership of this monitor and waits until another thread
notifies threads waiting on this object's monitor to wake up
either through a call to the notify
method or the
notifyAll
method. The thread then waits until it can
re-obtain ownership of the monitor and resumes execution.
As in the one argument version, interrupts and spurious wakeups are possible, and this method should always be used in a loop:
synchronized (obj) { while (<condition does not hold>) obj.wait(); ... // Perform action appropriate to condition }This method should only be called by a thread that is the owner of this object's monitor. See the
notify
method for a
description of the ways in which a thread can become the owner of
a monitor.The current thread must own this object's monitor.
This method causes the current thread (call it T) to place itself in the wait set for this object and then to relinquish any and all synchronization claims on this object. Thread T becomes disabled for thread scheduling purposes and lies dormant until one of four things happens:
A thread can also wake up without being notified, interrupted, or timing out, a so-called spurious wakeup. While this will rarely occur in practice, applications must guard against it by testing for the condition that should have caused the thread to be awakened, and continuing to wait if the condition is not satisfied. In other words, waits should always occur in loops, like this one:
synchronized (obj) { while (<condition does not hold>) obj.wait(timeout); ... // Perform action appropriate to condition }(For more information on this topic, see Section 3.2.3 in Doug Lea's "Concurrent Programming in Java (Second Edition)" (Addison-Wesley, 2000), or Item 50 in Joshua Bloch's "Effective Java Programming Language Guide" (Addison-Wesley, 2001).
If the current thread is interrupted by another thread while it is waiting, then an InterruptedException is thrown. This exception is not thrown until the lock status of this object has been restored as described above.
Note that the wait method, as it places the current thread into the wait set for this object, unlocks only this object; any other objects on which the current thread may be synchronized remain locked while the thread waits.
This method should only be called by a thread that is the owner
of this object's monitor. See the notify
method for a
description of the ways in which a thread can become the owner of
a monitor.
This method is similar to the wait
method of one
argument, but it allows finer control over the amount of time to
wait for a notification before giving up. The amount of real time,
measured in nanoseconds, is given by:
1000000*timeout+nanos
In all other respects, this method does the same thing as the method of one argument. In particular, wait(0, 0) means the same thing as wait(0).
The current thread must own this object's monitor. The thread releases ownership of this monitor and waits until either of the following two conditions has occurred:
notify
method
or the notifyAll
method.
timeout
milliseconds plus nanos
nanoseconds arguments, has
elapsed.
The thread then waits until it can re-obtain ownership of the monitor and resumes execution.
As in the one argument version, interrupts and spurious wakeups are possible, and this method should always be used in a loop:
synchronized (obj) { while (<condition does not hold>) obj.wait(timeout, nanos); ... // Perform action appropriate to condition }This method should only be called by a thread that is the owner of this object's monitor. See the
notify
method for a
description of the ways in which a thread can become the owner of
a monitor.