/[classpath]/classpath/vm/reference/java/lang/reflect/Method.java
ViewVC logotype

Diff of /classpath/vm/reference/java/lang/reflect/Method.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.2 by shalom, Thu Feb 11 21:09:14 1999 UTC revision 1.3 by ericb, Sat Oct 20 03:14:28 2001 UTC
# Line 1  Line 1 
1  /*  /* java.lang.reflect.Method - reflection of Java methods
2   * java.lang.reflect.Method: part of the Java Class Libraries project.     Copyright (C) 1998, 2001 Free Software Foundation, Inc.
3   * Copyright (C) 1998 Free Software Foundation  
4   *  This file is part of GNU Classpath.
5   * This library is free software; you can redistribute it and/or  
6   * modify it under the terms of the GNU Library General Public  GNU Classpath is free software; you can redistribute it and/or modify
7   * License as published by the Free Software Foundation; either  it under the terms of the GNU General Public License as published by
8   * version 2 of the License, or (at your option) any later version.  the Free Software Foundation; either version 2, or (at your option)
9   *  any later version.
10   * This library is distributed in the hope that it will be useful,  
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of  GNU Classpath is distributed in the hope that it will be useful, but
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU  WITHOUT ANY WARRANTY; without even the implied warranty of
13   * Library General Public License for more details.  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   *  General Public License for more details.
15   * You should have received a copy of the GNU Library General Public  
16   * License along with this library; if not, write to the  You should have received a copy of the GNU General Public License
17   * Free Software Foundation, Inc., 59 Temple Place - Suite 330,  along with GNU Classpath; see the file COPYING.  If not, write to the
18   * Boston, MA  02111-1307, USA.  Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19   */  02111-1307 USA.
20    
21    As a special exception, if you link this library with other files to
22    produce an executable, this library does not by itself cause the
23    resulting executable to be covered by the GNU General Public License.
24    This exception does not however invalidate any other reasons why the
25    executable file might be covered by the GNU General Public License. */
26    
27    
28  package java.lang.reflect;  package java.lang.reflect;
29    
30  /**  /**
31   ** Method is a class which represents a method.   * The Method class represents a member method of a class. It also allows
32   ** You may get information about it and make calls on it.<P>   * dynamic invocation, via reflection. This works for both static and
33   **   * instance methods. Invocation on Method objects knows how to do
34   ** <STRONG>Note:</STRONG> This class returns and accepts types as Classes, even primitive types; there are Class   * widening conversions, but throws {@link IllegalArgumentException} if
35   ** types defined that represent each different primitive type.  They are <code>java.lang.Boolean.TYPE,   * a narrowing conversion would be necessary. You can query for information
36   ** java.lang.Byte.TYPE, </code>etc.  These are not to be confused with the classes   * on this Method regardless of location, but invocation access may be limited
37   ** <code>java.lang.Boolean, java.lang.Byte</code>, etc., which are real classes.<P>   * by Java language access controls. If you can't do it in the compiler, you
38   **   * can't normally do it here either.<p>
39   ** <STRONG>Serialization:</STRONG>Note that this is not a serializable class.  It is entirely feasible to make it   *
40   ** serializable, but this is on Sun, not me.<P>   * <B>Note:</B> This class returns and accepts types as Classes, even
41   **   * primitive types; there are Class types defined that represent each
42   ** <STRONG>Access and Security:</STRONG> Once this Method is created by java.lang.Class (which does its own   * different primitive type.  They are <code>java.lang.Boolean.TYPE,
43   ** security check), any object may query it for information like parameter types, exception types, etc.   * java.lang.Byte.TYPE,</code>, also available as <code>boolean.class,
44   ** However, the Method may only be invoked using standard Java language access controls.  The JLS says that   * byte.class</code>, etc.  These are not to be confused with the
45   ** reflective access to all private, public and protected reflective members is granted to any class which   * classes <code>java.lang.Boolean, java.lang.Byte</code>, etc., which are
46   ** can be linked against the reflected member.  Link-level enforcement is the enforcement of public, private,   * real classes.<p>
47   ** protected and default access rules, based on the caller's relationship to the class (same package,   *
48   ** subclass, or unrelated).  Thus, if you couldn't normally invoke this method from the calling class, you   * Also note that this is not a serializable class.  It is entirely feasible
49   ** can't do it using a Method object either.<P>   * to make it serializable using the Externalizable interface, but this is
50   **   * on Sun, not me.
51   ** The relevant section of the VM spec on link-security is <A   *
52   ** HREF='http://java.sun.com/docs/books/vmspec/html/Concepts.doc.html#22574'>2.16.3</A>, under Resolution.   * @author John Keiser
53   ** A summary of the appropriate rules follows.<P>   * @author Eric Blake <ebb9@email.byu.edu>
54   **   * @see Member
55   ** <STRONG>Summary of access rules</STRONG><BR>   * @see Class
56   ** Two checks are done, and they are the same checks--on both the member's class and the member itself:   * @see java.lang.Class#getMethod(String,Object[])
57   ** <UL>   * @see java.lang.Class#getDeclaredMethod(String,Object[])
58   ** <LI>If the caller is the same class as the member's class, then it can access the member no matter   * @see java.lang.Class#getMethods()
59   ** what.</LI>   * @see java.lang.Class#getDeclaredMethods()
60   ** <LI>If the caller is in the same package as the member's class, then the member's class and the member   * @since 1.1
61   ** itself must both be public, protected or default access.</LI>   * @status updated to 1.4
62   ** <LI>If the caller is a subclass of the member's class, then the member's class and the member itself must   */
63   ** both be public or protected access.</LI>  public final class Method
64   ** <LI>If the caller is in the same package as the member's class, then the member's class and the member must  extends AccessibleObject implements Member
65   ** be public access.</LI>  {
66   ** </UL>    Class declaringClass;
67   ** <P>    String name;
68   **    int slot;
69   ** As far as I can tell from the fairly confusing <A  
70   ** HREF='http://java.sun.com/products/jdk/1.1/docs/guide/innerclasses/spec/innerclasses.doc.html'>Inner    /**
71   ** Classes Specification</A>, there should be no change to these rules from the addition of inner     * This class is uninstantiable.
72   ** classes in 1.1.<P>     */
73   **    private Method(Class declaringClass, String name, int slot)
74   ** <STRONG>Version note:</STRONG> In 1.2, the security checks can be disabled in the AccessibleObject    {
75   ** interface.  But this ain't 1.2. :)<P>      this.declaringClass = declaringClass;
76   **      this.name = name;
77   ** <STRONG>BUGS:</STRONG> The maximum size of a signature right now is 4096 characters because I'm using      this.slot = slot;
78   ** a static buffer when I calculate them.  While fine for most purposes, it is for pathological cases that    }
79   ** specs are built.  I'm not sure how I'll handle this yet.  
80   **    /**
81   ** @author John Keiser     * Gets the class that declared this method, or the class where this method
82   ** @version 1.1.0, 31 May 1998     * is a non-inherited member.
83   ** @see Member     * @return the class that declared this member
84   ** @see java.lang.Class#getMethod(String,Object[])     */
85   ** @see java.lang.Class#getDeclaredMethod(String,Object[])    public Class getDeclaringClass()
86   ** @see java.lang.Class#getMethods()    {
87   ** @see java.lang.Class#getDeclaredMethods()      return declaringClass;
88   **/    }
89    
90  public final class Method implements Member {    /**
91          Class declaringClass;     * Gets the name of this method.
92          String name;     * @return the name of this method
93          int slot;     */
94      public String getName()
95          /* This class is uninstantiable. */    {
96          private Method(Class declaringClass, String name, int slot) {      return name;
97                  this.declaringClass = declaringClass;    }
98                  this.name = name;  
99                  this.slot = slot;    /**
100          }     * Gets the modifiers this method uses.  Use the <code>Modifier</code>
101       * class to interpret the values.  A method can only have a subset of the
102          /** Gets the class that declared this method.     * following modifiers: public, private, protected, abstract, static,
103           ** <STRONG>It is unclear whether this returns the class that actually syntactically declared     * final, synchronized, native, and strictfp.
104           ** the member, or the class where the Method object was gotten from.</STRONG>     *
105           ** @return the class that declared this member.     * @return an integer representing the modifiers to this Member
106           **/     * @see Modifier
107          public Class getDeclaringClass() {     */
108                  return declaringClass;    public native int getModifiers();
109          }  
110      /**
111          /** Gets the modifiers this method uses.  Use the <code>Modifier</code>     * Gets the return type of this method.
112           ** class to interpret the values.     * @return the type of this method
113           ** A Method may only have the modifiers public, private, protected, abstract,     */
114           ** static, final, synchronized, and native.    public native Class getReturnType();
115           ** @see Modifier  
116           ** @return an integer representing the modifiers to this Member.    /**
117           **/     * Get the parameter list for this method, in declaration order. If the
118          public native int getModifiers();     * method takes no parameters, returns a 0-length array (not null).
119       *
120          /** Gets the name of this method.     * @return a list of the types of the method's parameters
121           ** @return the name of this method.     */
122           **/    public native Class[] getParameterTypes();
123          public String getName() {  
124                  return name;    /**
125          }     * Get the exception types this method says it throws, in no particular
126       * order. If the method has no throws clause, returns a 0-length array
127          /** Gets the return type of this method.     * (not null).
128           ** @return the type of this method.     *
129           **/     * @return a list of the types in the method's throws clause
130          public native Class getReturnType();     */
131      public native Class[] getExceptionTypes();
132          /** Get the parameter list for this method.  
133           ** @return a list of classes representing the names of the method's parameters.    /**
134           **/     * Compare two objects to see if they are semantically equivalent.
135          public native Class[] getParameterTypes();     * Two Methods are semantically equivalent if they have the same declaring
136       * class, name, and parameter list.  This ignores different exception
137          /** Get the exception types this method says it throws.     * clauses, but since you can't create a Method except through the VM,
138           ** @return a list of classes representing the exception types.     * this is just the == relation.
139           **/     *
140          public native Class[] getExceptionTypes();     * @param o the object to compare to
141       * @return <code>true</code> if they are equal; <code>false</code> if not
142          /** Compare two objects to see if they are semantically equivalent.     */
143           ** Two Methods are semantically equivalent if they have the same declaring class, name,    public boolean equals(Object o)
144           ** and parameter list.  <STRONG>Though I really don't see how two different Method objects    {
145           ** with identical parameters could be created.</STRONG>      return this == o;
146           ** @param o the object to compare to.    }
147           ** @return <code>true</code> if they are equal; <code>false</code> if not.  
148           **/    /**
149          public boolean equals(Object o) {     * Get the hash code for the Method. The Method hash code is the hash code
150                  return this == o;     * of its name XOR'd with the hash code of its class name.
151          }     *
152       * @return the hash code for the object
153          /** Get the hash code for the Method.     */
154           ** Constructor hash code is the hash code of the declaring class's name XOR'd with the method name.    public int hashCode()
155           ** @return the hash code for the object.    {
156           **/      return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
157          public int hashCode() {    }
158                  return getDeclaringClass().getName().hashCode() ^ getName().hashCode();  
159          }    /**
160       * Get a String representation of the Method. A Method's String
161          /** Get a String representation of the Constructor.     * representation is "&lt;modifiers&gt; &lt;returntype&gt;
162           ** A Constructor's String representation is &lt;modifiers&gt; &lt;returntype&gt; &lt;methodname&gt;(&lt;paramtypes&gt;).     * &lt;methodname&gt;(&lt;paramtypes&gt;) throws &lt;exceptions&gt;", where
163           ** Example: <code>public static int run(java.lang.Runnable,int)</code>     * everything after ')' is omitted if there are no exceptions.<br> Example:
164           ** @return the String representation of the Constructor.     * <code>public static int run(java.lang.Runnable,int)</code>
165           **/     *
166          public String toString() {     * @return the String representation of the Method
167                  StringBuffer sb = new StringBuffer();     */
168                  sb.append(Modifier.toString(getModifiers()));    public String toString()
169                  sb.append(' ');    {
170                  sb.append(getReturnType());      StringBuffer sb = new StringBuffer();
171                  sb.append(' ');      Modifier.toString(getModifiers(), sb).append(' ');
172                  sb.append(getDeclaringClass().getName());      sb.append(getReturnType()).append(' ');
173                  sb.append('.');      sb.append(getDeclaringClass().getName()).append('.');
174                  sb.append(getName());      sb.append(getName()).append('(');
175                  sb.append('(');      Class[] c = getParameterTypes();
176                  Class[] c = getParameterTypes();      if (c.length > 0)
177                  if(c.length > 0) {        {
178                          sb.append(c[0].getName());          sb.append(c[0].getName());
179                          for(int i = 1; i < c.length; i++) {          for (int i = 1; i < c.length; i++)
180                                  sb.append(',');            sb.append(',').append(c[i].getName());
181                                  sb.append(c[i].getName());        }
182                          }      sb.append(')');
183                  }      c = getExceptionTypes();
184                  sb.append(')');      if (e.length > 0)
185                  return sb.toString();        {
186          }          sb.append(" throws ").append(c[0].getName());
187            for (int i = 1; i < c.length; i++)
188              sb.append(',').append(c[i].getName());
189          /** Invoke the method.<P>        }
190           ** The method will permit widening argument conversions, but not narrowing conversions.<P>      return sb.toString();
191           ** For static methods, declaringClass is used for the Method lookup, not the class of the Object    }
192           ** being invoked on.<P>  
193           ** For instance methods, the method in the class of the Object itself is invoked.<P>    /**
194           **     * Invoke the method. Arguments are automatically unwrapped and widened,
195           ** The permissions and workings of this method are the same as if you had invoked the method in Java     * and the result is automatically wrapped, if needed.<p>
196           ** using ((<declaringClass>)o).<methodName>(<args>).  If your object had enough permissions to do     *
197           ** that, then this call will succeed.<P>     * If the method is static, <code>o</code> will be ignored. Otherwise,
198           **     * the method uses dynamic lookup as described in JLS 15.12.4.4. You cannot
199           ** <STRONG>Robustness Note:</STRONG> if the method returns an Object of the wrong type somehow, then     * mimic the behavior of nonvirtual lookup (as in super.foo()). This means
200           ** that will not be checked by invoke().  Shouldn't happen anyway, but this information is included     * you will get a <code>NullPointerException</code> if <code>o</code> is
201           ** for completeness.     * null, and an <code>IllegalArgumentException</code> if it is incompatible
202           **     * with the declaring class of the method. If the method takes 0 arguments,
203           ** @param o the object to invoke the method on.     * you may use null or a 0-length array for <code>args</code>.<p>
204           ** @param args the arguments to the method.     *
205           ** @return the return value of the method, wrapped in the appropriate wrapper if it is primitive.     * Next, if this Method enforces access control, your runtime context is
206           ** @exception IllegalAccessException           if the method could not normally be called     * evaluated, and you may have an <code>IllegalAccessException</code> if
207           **                                             by the Java code (see note at beginning of class     * you could not acces this method in similar compiled code. If the method
208           **                                             for more information).     * is static, and its class is uninitialized, you trigger class
209           ** @exception IllegalArgumentException         if the number of arguments is incorrect; if the     * initialization, which may end in a
210           **                                             arguments cannot be converted to the actual argument     * <code>ExceptionInInitializerError</code>.<p>
211           **                                             types, even with a widening conversion; for instance     *
212           **                                             methods, if the Object invoked on is not of appropriate     * Finally, the method is invoked. If it completes normally, the return value
213           **                                             type.     * will be null for a void method, a wrapped object for a primitive return
214           ** @exception InvocationTargetException        if the method throws an exception.     * method, or the actual return of an Object method. If it completes
215           **/     * abruptly, the exception is wrapped in an
216          public Object invoke(Object o, Object[] args)     * <code>InvocationTargetException</code>.
217                  throws IllegalAccessException,     *
218                         IllegalArgumentException,     * @param o the object to invoke the method on
219                         InvocationTargetException {     * @param args the arguments to the method
220                  return invokeNative(o, args, declaringClass, slot);     * @return the return value of the method, wrapped in the appropriate
221          }     *         wrapper if it is primitive
222       * @throws IllegalAccessException if the method could not normally be called
223          /*     *         by the Java code (i.e. it is not public)
224           * NATIVE HELPERS     * @throws IllegalArgumentException if the number of arguments is incorrect;
225           */     *         if the arguments types are wrong even with a widening conversion;
226       *         or if <code>o</code> is not an instance of the class or interface
227          private native Object invokeNative(Object o, Object[] args,     *         declaring this method
228                          Class declaringClass, int slot);     * @throws InvocationTargetException if the method throws an exception
229       * @throws NullPointerException if <code>o</code> is null and this field
230       *         requires an instance
231       * @throws ExceptionInInitializerError if accessing a static method triggered
232       *         class initialization, which then failed
233       */
234      public Object invoke(Object o, Object[] args)
235        throws IllegalAccessException, InvocationTargetException
236      {
237        return invokeNative(o, args, declaringClass, slot);
238      }
239    
240      /*
241       * NATIVE HELPERS
242       */
243    
244      private native Object invokeNative(Object o, Object[] args,
245                                         Class declaringClass, int slot)
246        throws IllegalAccessException, InvocationTargetException;
247  }  }

Legend:
Removed from v.1.2  
changed lines
  Added in v.1.3

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26