home *** CD-ROM | disk | FTP | other *** search
/ Java 1.2 How-To / JavaHowTo.iso / 3rdParty / jbuilder / unsupported / JDK1.2beta3 / SOURCE / SRC.ZIP / java / lang / reflect / Method.java < prev    next >
Encoding:
Java Source  |  1998-03-20  |  9.8 KB  |  282 lines

  1. /*
  2.  * @(#)Method.java    1.19 98/03/18
  3.  *
  4.  * Copyright 1996, 1997 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  *
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15. package java.lang.reflect;
  16.  
  17. /**
  18.  * A Method provides information about, and access to, a single method
  19.  * on a class or interface.  The reflected method may be a class method
  20.  * or an instance method (including an abstract method).
  21.  *
  22.  * <p>A Method permits widening conversions to occur when matching the
  23.  * actual parameters to invokewith the underlying method's formal
  24.  * parameters, but it throws an IllegalArgumentException if a
  25.  * narrowing conversion would occur.
  26.  *
  27.  * @see Member
  28.  * @see java.lang.Class
  29.  * @see java.lang.Class#getMethods()
  30.  * @see java.lang.Class#getMethod()
  31.  * @see java.lang.Class#getDeclaredMethods()
  32.  * @see java.lang.Class#getDeclaredMethod()
  33.  *
  34.  * @author Nakul Saraiya
  35.  */
  36. public final
  37. class Method extends AccessibleObject implements Member {
  38.  
  39.     private Class        clazz;
  40.     private int            slot;
  41.     private String        name;
  42.     private Class        returnType;
  43.     private Class[]        parameterTypes;
  44.     private Class[]        exceptionTypes;
  45.     private int            modifiers;
  46.  
  47.     /**
  48.      * Constructor.  Only the Java Virtual Machine may construct a Method.
  49.      */
  50.     private Method() {}
  51.  
  52.     /**
  53.      * Returns the Class object representing the class or interface
  54.      * that declares the method represented by this Method object.
  55.      */
  56.     public Class getDeclaringClass() {
  57.     return clazz;
  58.     }
  59.  
  60.     /**
  61.      * Returns the name of the method represented by this Method
  62.      * object, as a String.
  63.      */
  64.     public String getName() {
  65.     return name;
  66.     }
  67.  
  68.     /**
  69.      * Returns the Java language modifiers for the method represented
  70.      * by this Method object, as an integer. The Modifier class should
  71.      * be used to decode the modifiers.
  72.      *
  73.      * @see Modifier
  74.      */
  75.     public int getModifiers() {
  76.     return modifiers;
  77.     }
  78.  
  79.     /**
  80.      * Returns a Class object that represents the formal return type
  81.      * of the method represented by this Method object.
  82.      */
  83.     public Class getReturnType() {
  84.     return returnType;
  85.     }
  86.  
  87.     /**
  88.      * Returns an array of Class objects that represent the formal
  89.      * parameter types, in declaration order, of the method
  90.      * represented by this Method object.  Returns an array of length
  91.      * 0 if the underlying method takes no parameters.
  92.      */
  93.     public Class[] getParameterTypes() {
  94.     return copy(parameterTypes);
  95.     }
  96.  
  97.     /**
  98.      * Returns an array of Class objects that represent the types of
  99.      * the checked exceptions thrown by the underlying method
  100.      * represented by this Method object.  Returns an array of length
  101.      * 0 if the method throws no checked exceptions.
  102.      */
  103.     public Class[] getExceptionTypes() {
  104.     return copy(exceptionTypes);
  105.     }
  106.  
  107.     /**
  108.      * Compares this Method against the specified object.  Returns
  109.      * true if the objects are the same.  Two Methods are the same if
  110.      * they were declared by the same class and have the same name
  111.      * and formal parameter types.
  112.      */
  113.     public boolean equals(Object obj) {
  114.     if (obj != null && obj instanceof Method) {
  115.         Method other = (Method)obj;
  116.         if ((getDeclaringClass() == other.getDeclaringClass())
  117.         && (getName().equals(other.getName()))) {
  118.         /* Avoid unnecessary cloning */
  119.         Class[] params1 = parameterTypes;
  120.         Class[] params2 = other.parameterTypes;
  121.         if (params1.length == params2.length) {
  122.             for (int i = 0; i < params1.length; i++) {
  123.             if (params1[i] != params2[i])
  124.                 return false;
  125.             }
  126.             return true;
  127.         }
  128.         }
  129.     }
  130.     return false;
  131.     }
  132.  
  133.     /**
  134.      * Returns a hashcode for this Method.  The hashcode is computed
  135.      * as the exclusive-or of the hashcodes for the underlying
  136.      * method's declaring class name and the method's name.
  137.      */
  138.     public int hashCode() {
  139.     return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
  140.     }
  141.  
  142.     /**
  143.      * Returns a string describing this Method.  The string is
  144.      * formatted as the method access modifiers, if any, followed by
  145.      * the method return type, followed by a space, followed by the
  146.      * class declaring the method, followed by a period, followed by
  147.      * the method name, followed by a parenthesized, comma-separated
  148.      * list of the method's formal parameter types. If the method
  149.      * throws checked exceptions, the parameter list is followed by a
  150.      * space, followed by the word throws followed by a
  151.      * comma-separated list of the thrown exception types.
  152.      * For example:
  153.      * <pre>
  154.      *    public boolean java.lang.Object.equals(java.lang.Object)
  155.      * </pre>
  156.      *
  157.      * <p>The access modifiers are placed in canonical order as
  158.      * specified by "The Java Language Specification".  This is
  159.      * <tt>public</tt>, <tt>protected</tt> or <tt>private</tt> first,
  160.      * and then other modifiers in the following order:
  161.      * <tt>abstract</tt>, <tt>static</tt>, <tt>final</tt>,
  162.      * <tt>synchronized</tt> <tt>native</tt>.
  163.      */
  164.     public String toString() {
  165.     try {
  166.         StringBuffer sb = new StringBuffer();
  167.         int mod = getModifiers();
  168.         if (mod != 0) {
  169.         sb.append(Modifier.toString(mod) + " ");
  170.         }
  171.         sb.append(Field.getTypeName(getReturnType()) + " ");
  172.         sb.append(Field.getTypeName(getDeclaringClass()) + ".");
  173.         sb.append(getName() + "(");
  174.         Class[] params = parameterTypes; // avoid clone
  175.         for (int j = 0; j < params.length; j++) {
  176.         sb.append(Field.getTypeName(params[j]));
  177.         if (j < (params.length - 1))
  178.             sb.append(",");
  179.         }
  180.         sb.append(")");
  181.         Class[] exceptions = exceptionTypes; // avoid clone
  182.         if (exceptions.length > 0) {
  183.         sb.append(" throws ");
  184.         for (int k = 0; k < exceptions.length; k++) {
  185.             sb.append(exceptions[k].getName());
  186.             if (k < (exceptions.length - 1))
  187.             sb.append(",");
  188.         }
  189.         }
  190.         return sb.toString();
  191.     } catch (Exception e) {
  192.         return "<" + e + ">";
  193.     }
  194.     }
  195.  
  196.     /**
  197.      * Invokes the underlying method represented by this Method
  198.      * object, on the specified object with the specified parameters.
  199.      * Individual parameters are automatically unwrapped to match
  200.      * primitive formal parameters, and both primitive and reference
  201.      * parameters are subject to widening conversions as
  202.      * necessary. The value returned by the underlying method is
  203.      * automatically wrapped in an object if it has a primitive type.
  204.      *
  205.      * <p>Method invocation proceeds with the following steps, in order:
  206.      *
  207.      * <p>If the underlying method is static, then the specified object
  208.      * argument is ignored. It may be null.
  209.      *
  210.      * <p>Otherwise, the method is an instance method.  If the specified
  211.      * object argument is null, the invocation throws a
  212.      * NullPointerException.  Otherwise, if the specified object
  213.      * argument is not an instance of the class or interface declaring
  214.      * the underlying method, the invocation throws an
  215.      * IllegalArgumentException.
  216.      *
  217.      * <p>If this Method object enforces Java language access control and
  218.      * the underlying method is inaccessible, the invocation throws an
  219.      * IllegalAccessException.
  220.      *
  221.      * <p>If the number of actual parameters supplied via args is
  222.      * different from the number of formal parameters required by the
  223.      * underlying method, the invocation throws an
  224.      * IllegalArgumentException.
  225.      *
  226.      * <p>For each actual parameter in the supplied args array:
  227.      *
  228.      * <p>If the corresponding formal parameter has a primitive type, an
  229.      * unwrapping conversion is attempted to convert the object value
  230.      * to a value of a primitive type.  If this attempt fails, the
  231.      * invocation throws an IllegalArgumentException.
  232.      *
  233.      * <p>If, after possible unwrapping, the parameter value cannot be
  234.      * converted to the corresponding formal parameter type by an
  235.      * identity or widening conversion, the invocation throws an
  236.      * IllegalArgumentException.
  237.      *
  238.      * <p>If the underlying method is an instance method, it is invoked
  239.      * using dynamic method lookup as documented in The Java Language
  240.      * Specification, section 15.11.4.4; in particular, overriding
  241.      * based on the runtime type of the target object will occur.
  242.      *
  243.      * <p>If the underlying method is static, it is invoked as exactly
  244.      * the method on the declaring class.
  245.      *
  246.      * <p>Control transfers to the underlying method.  If the method
  247.      * completes abruptly by throwing an exception, the exception is
  248.      * placed in an InvocationTargetException and thrown in turn to
  249.      * the caller of invoke.
  250.      *
  251.      * <p>If the method completes normally, the value it returns is
  252.      * returned to the caller of invoke; if the value has a primitive
  253.      * type, it is first appropriately wrapped in an object. If the
  254.      * underlying method return type is void, the invocation returns
  255.      * null.
  256.      *
  257.      * @exception IllegalAccessException    if the underlying method
  258.      *              is inaccessible.
  259.      * @exception IllegalArgumentException  if the number of actual and formal
  260.      *              parameters differ, or if an unwrapping conversion fails.
  261.      * @exception InvocationTargetException if the underlying method
  262.      *              throws an exception.
  263.      * @exception NullPointerException      if the specified object is null.
  264.      */
  265.     public native Object invoke(Object obj, Object[] args)
  266.     throws IllegalAccessException, IllegalArgumentException,
  267.         InvocationTargetException;
  268.  
  269.     /*
  270.      * Avoid clone()
  271.      */
  272.     static Class[] copy(Class[] in) {
  273.     int l = in.length;
  274.     if (l == 0)
  275.         return in;
  276.     Class[] out = new Class[l];
  277.     for (int i = 0; i < l; i++)
  278.         out[i] = in[i];
  279.     return out;
  280.     }
  281. }
  282.