Source for java.lang.reflect.InvocationHandler

   1: /* java.lang.reflect.InvocationHandler - dynamically executes methods in
   2:    proxy instances
   3:    Copyright (C) 2001 Free Software Foundation, Inc.
   4: 
   5: This file is part of GNU Classpath.
   6: 
   7: GNU Classpath is free software; you can redistribute it and/or modify
   8: it under the terms of the GNU General Public License as published by
   9: the Free Software Foundation; either version 2, or (at your option)
  10: any later version.
  11: 
  12: GNU Classpath is distributed in the hope that it will be useful, but
  13: WITHOUT ANY WARRANTY; without even the implied warranty of
  14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15: General Public License for more details.
  16: 
  17: You should have received a copy of the GNU General Public License
  18: along with GNU Classpath; see the file COPYING.  If not, write to the
  19: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  20: 02110-1301 USA.
  21: 
  22: Linking this library statically or dynamically with other modules is
  23: making a combined work based on this library.  Thus, the terms and
  24: conditions of the GNU General Public License cover the whole
  25: combination.
  26: 
  27: As a special exception, the copyright holders of this library give you
  28: permission to link this library with independent modules to produce an
  29: executable, regardless of the license terms of these independent
  30: modules, and to copy and distribute the resulting executable under
  31: terms of your choice, provided that you also meet, for each linked
  32: independent module, the terms and conditions of the license of that
  33: module.  An independent module is a module which is not derived from
  34: or based on this library.  If you modify this library, you may extend
  35: this exception to your version of the library, but you are not
  36: obligated to do so.  If you do not wish to do so, delete this
  37: exception statement from your version. */
  38: 
  39: 
  40: package java.lang.reflect;
  41: 
  42: /**
  43:  * This interface defines an invocation handler.  Suppose you are using
  44:  * reflection, and found a method that requires that its parameter
  45:  * be an object of a given interface.  You want to call this method,
  46:  * but have no idea what classes implement that interface.  So, you can
  47:  * create a {@link Proxy} instance, a convenient way to dynamically
  48:  * generate a class that meets all the necessary properties of that
  49:  * interface.  But in order for the proxy instance to do any good, it
  50:  * needs to know what to do when interface methods are invoked!  So,
  51:  * this interface is basically a cool wrapper that provides runtime
  52:  * code generation needed by proxy instances.
  53:  *
  54:  * <p>While this interface was designed for use by Proxy, it will also
  55:  * work on any object in general.</p>
  56:  *
  57:  * <p>Hints for implementing this class:</p>
  58:  *
  59:  * <ul>
  60:  * <li>Don't forget that Object.equals, Object.hashCode, and
  61:  *     Object.toString will call this handler.  In particular,
  62:  *     a naive call to proxy.equals, proxy.hashCode, or proxy.toString
  63:  *     will put you in an infinite loop.  And remember that string
  64:  *     concatenation also invokes toString.</li>
  65:  * <li>Obey the contract of the Method object you are handling, or
  66:  *     the proxy instance will be forced to throw a
  67:  *     {@link NullPointerException}, {@link ClassCastException},
  68:  *     or {@link UndeclaredThrowableException}.</li>
  69:  * <li>Be prepared to wrap/unwrap primitives as necessary.</li>
  70:  * <li>The Method object may be owned by a different interface than
  71:  *     what was actually used as the qualifying type of the method
  72:  *     invocation in the Java source code. This means that it might
  73:  *     not always be safe to throw an exception listed as belonging
  74:  *     to the method's throws clause.</li>
  75:  * </ul>
  76:  *
  77:  * <p><small>For a fun time, create an InvocationHandler that handles the
  78:  * methods of a proxy instance of the InvocationHandler interface!</small></p>
  79:  *
  80:  * @see Proxy
  81:  * @see UndeclaredThrowableException
  82:  *
  83:  * @author Eric Blake (ebb9@email.byu.edu)
  84:  * @since 1.3
  85:  * @status updated to 1.4
  86:  */
  87: public interface InvocationHandler
  88: {
  89:   /**
  90:    * When a method is invoked on a proxy instance, it is wrapped and
  91:    * this method is called instead, so that you may decide at runtime
  92:    * how the original method should behave.
  93:    *
  94:    * @param proxy the instance that the wrapped method should be
  95:    *        invoked on.  When this method is called by a Proxy object,
  96:    *        `proxy' will be an instance of {@link Proxy}, and oddly enough,
  97:    *        <code>Proxy.getInvocationHandler(proxy)</code> will return
  98:    *        <code>this</code>!
  99:    * @param method the reflected method to invoke on the proxy.
 100:    *        When this method is called by a Proxy object, 'method'
 101:    *        will be the reflection object owned by the declaring
 102:    *        class or interface, which may be a supertype of the
 103:    *        interfaces the proxy directly implements.
 104:    * @param args the arguments passed to the original method, or
 105:    *        <code>null</code> if the method takes no arguments.
 106:    *        (But also be prepared to handle a 0-length array).
 107:    *        Arguments of primitive type, such as <code>boolean</code>
 108:    *        or <code>int</code>, are wrapped in the appropriate
 109:    *        class such as {@link Boolean} or {@link Integer}.
 110:    * @return whatever is necessary to return from the wrapped method.
 111:    *         If the wrapped method is <code>void</code>, the proxy
 112:    *         instance will ignore it.  If the wrapped method returns
 113:    *         a primitive, this must be the correct wrapper type whose value
 114:    *         is exactly assignable to the appropriate type (no widening
 115:    *         will be performed); a null object in this case causes a
 116:    *         {@link NullPointerException}.  In all remaining cases, if
 117:    *         the returned object is not assignment compatible to the
 118:    *         declared type of the original method, the proxy instance
 119:    *         will generate a {@link ClassCastException}.
 120:    * @throws Throwable this interface is listed as throwing anything,
 121:    *         but the implementation should only throw unchecked
 122:    *         exceptions and exceptions listed in the throws clause of
 123:    *         all methods being overridden by the proxy instance.  If
 124:    *         something is thrown that is not compatible with the throws
 125:    *         clause of all overridden methods, the proxy instance will
 126:    *         wrap the exception in an UndeclaredThrowableException.
 127:    *         Note that an exception listed in the throws clause of the
 128:    *         `method' parameter might not be declared in additional
 129:    *         interfaces also implemented by the proxy object.
 130:    *
 131:    * @see Proxy
 132:    * @see UndeclaredThrowableException
 133:    */
 134:   Object invoke(Object proxy, Method method, Object[] args)
 135:     throws Throwable;
 136: 
 137: }