1. /*
  2. * @(#)Method.java 1.36 03/01/23
  3. *
  4. * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.lang.reflect;
  8. import sun.reflect.MethodAccessor;
  9. import sun.reflect.Reflection;
  10. /**
  11. * A <code>Method</code> provides information about, and access to, a single method
  12. * on a class or interface. The reflected method may be a class method
  13. * or an instance method (including an abstract method).
  14. *
  15. * <p>A <code>Method</code> permits widening conversions to occur when matching the
  16. * actual parameters to invokewith the underlying method's formal
  17. * parameters, but it throws an <code>IllegalArgumentException</code> if a
  18. * narrowing conversion would occur.
  19. *
  20. * @see Member
  21. * @see java.lang.Class
  22. * @see java.lang.Class#getMethods()
  23. * @see java.lang.Class#getMethod(String, Class[])
  24. * @see java.lang.Class#getDeclaredMethods()
  25. * @see java.lang.Class#getDeclaredMethod(String, Class[])
  26. *
  27. * @author Kenneth Russell
  28. * @author Nakul Saraiya
  29. */
  30. public final
  31. class Method extends AccessibleObject implements Member {
  32. private Class clazz;
  33. private int slot;
  34. // This is guaranteed to be interned by the VM in the 1.4
  35. // reflection implementation
  36. private String name;
  37. private Class returnType;
  38. private Class[] parameterTypes;
  39. private Class[] exceptionTypes;
  40. private int modifiers;
  41. private volatile MethodAccessor methodAccessor;
  42. // For sharing of MethodAccessors. This branching structure is
  43. // currently only two levels deep (i.e., one root Method and
  44. // potentially many Method objects pointing to it.)
  45. private Method root;
  46. // More complicated security check cache needed here than for
  47. // Class.newInstance() and Constructor.newInstance()
  48. private volatile Class securityCheckTargetClassCache;
  49. /**
  50. * Package-private constructor used by ReflectAccess to enable
  51. * instantiation of these objects in Java code from the java.lang
  52. * package via sun.reflect.LangReflectAccess.
  53. */
  54. Method(Class declaringClass,
  55. String name,
  56. Class[] parameterTypes,
  57. Class returnType,
  58. Class[] checkedExceptions,
  59. int modifiers,
  60. int slot)
  61. {
  62. this.clazz = declaringClass;
  63. this.name = name;
  64. this.parameterTypes = parameterTypes;
  65. this.returnType = returnType;
  66. this.exceptionTypes = checkedExceptions;
  67. this.modifiers = modifiers;
  68. this.slot = slot;
  69. }
  70. /**
  71. * Package-private routine (exposed to java.lang.Class via
  72. * ReflectAccess) which returns a copy of this Method. The copy's
  73. * "root" field points to this Method.
  74. */
  75. Method copy() {
  76. // This routine enables sharing of MethodAccessor objects
  77. // among Method objects which refer to the same underlying
  78. // method in the VM. (All of this contortion is only necessary
  79. // because of the "accessibility" bit in AccessibleObject,
  80. // which implicitly requires that new java.lang.reflect
  81. // objects be fabricated for each reflective call on Class
  82. // objects.)
  83. Method res = new Method(clazz, name, parameterTypes, returnType,
  84. exceptionTypes, modifiers, slot);
  85. res.root = this;
  86. // Might as well eagerly propagate this if already present
  87. res.methodAccessor = methodAccessor;
  88. return res;
  89. }
  90. /**
  91. * Returns the <code>Class</code> object representing the class or interface
  92. * that declares the method represented by this <code>Method</code> object.
  93. */
  94. public Class getDeclaringClass() {
  95. return clazz;
  96. }
  97. /**
  98. * Returns the name of the method represented by this <code>Method</code>
  99. * object, as a <code>String</code>.
  100. */
  101. public String getName() {
  102. return name;
  103. }
  104. /**
  105. * Returns the Java language modifiers for the method represented
  106. * by this <code>Method</code> object, as an integer. The <code>Modifier</code> class should
  107. * be used to decode the modifiers.
  108. *
  109. * @see Modifier
  110. */
  111. public int getModifiers() {
  112. return modifiers;
  113. }
  114. /**
  115. * Returns a <code>Class</code> object that represents the formal return type
  116. * of the method represented by this <code>Method</code> object.
  117. *
  118. * @return the return type for the method this object represents
  119. */
  120. public Class getReturnType() {
  121. return returnType;
  122. }
  123. /**
  124. * Returns an array of <code>Class</code> objects that represent the formal
  125. * parameter types, in declaration order, of the method
  126. * represented by this <code>Method</code> object. Returns an array of length
  127. * 0 if the underlying method takes no parameters.
  128. *
  129. * @return the parameter types for the method this object
  130. * represents
  131. */
  132. public Class[] getParameterTypes() {
  133. return copy(parameterTypes);
  134. }
  135. /**
  136. * Returns an array of <code>Class</code> objects that represent
  137. * the types of the exceptions declared to be thrown
  138. * by the underlying method
  139. * represented by this <code>Method</code> object. Returns an array of length
  140. * 0 if the method declares no exceptions in its <code>throws</code> clause.
  141. *
  142. * @return the exception types declared as being thrown by the
  143. * method this object represents
  144. */
  145. public Class[] getExceptionTypes() {
  146. return copy(exceptionTypes);
  147. }
  148. /**
  149. * Compares this <code>Method</code> against the specified object. Returns
  150. * true if the objects are the same. Two <code>Methods</code> are the same if
  151. * they were declared by the same class and have the same name
  152. * and formal parameter types and return type.
  153. */
  154. public boolean equals(Object obj) {
  155. if (obj != null && obj instanceof Method) {
  156. Method other = (Method)obj;
  157. if ((getDeclaringClass() == other.getDeclaringClass())
  158. && (getName() == other.getName())) {
  159. /* Avoid unnecessary cloning */
  160. Class[] params1 = parameterTypes;
  161. Class[] params2 = other.parameterTypes;
  162. if (params1.length == params2.length) {
  163. for (int i = 0; i < params1.length; i++) {
  164. if (params1[i] != params2[i])
  165. return false;
  166. }
  167. return true;
  168. }
  169. }
  170. }
  171. return false;
  172. }
  173. /**
  174. * Returns a hashcode for this <code>Method</code>. The hashcode is computed
  175. * as the exclusive-or of the hashcodes for the underlying
  176. * method's declaring class name and the method's name.
  177. */
  178. public int hashCode() {
  179. return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
  180. }
  181. /**
  182. * Returns a string describing this <code>Method</code>. The string is
  183. * formatted as the method access modifiers, if any, followed by
  184. * the method return type, followed by a space, followed by the
  185. * class declaring the method, followed by a period, followed by
  186. * the method name, followed by a parenthesized, comma-separated
  187. * list of the method's formal parameter types. If the method
  188. * throws checked exceptions, the parameter list is followed by a
  189. * space, followed by the word throws followed by a
  190. * comma-separated list of the thrown exception types.
  191. * For example:
  192. * <pre>
  193. * public boolean java.lang.Object.equals(java.lang.Object)
  194. * </pre>
  195. *
  196. * <p>The access modifiers are placed in canonical order as
  197. * specified by "The Java Language Specification". This is
  198. * <tt>public</tt>, <tt>protected</tt> or <tt>private</tt> first,
  199. * and then other modifiers in the following order:
  200. * <tt>abstract</tt>, <tt>static</tt>, <tt>final</tt>,
  201. * <tt>synchronized</tt> <tt>native</tt>.
  202. */
  203. public String toString() {
  204. try {
  205. StringBuffer sb = new StringBuffer();
  206. int mod = getModifiers();
  207. if (mod != 0) {
  208. sb.append(Modifier.toString(mod) + " ");
  209. }
  210. sb.append(Field.getTypeName(getReturnType()) + " ");
  211. sb.append(Field.getTypeName(getDeclaringClass()) + ".");
  212. sb.append(getName() + "(");
  213. Class[] params = parameterTypes; // avoid clone
  214. for (int j = 0; j < params.length; j++) {
  215. sb.append(Field.getTypeName(params[j]));
  216. if (j < (params.length - 1))
  217. sb.append(",");
  218. }
  219. sb.append(")");
  220. Class[] exceptions = exceptionTypes; // avoid clone
  221. if (exceptions.length > 0) {
  222. sb.append(" throws ");
  223. for (int k = 0; k < exceptions.length; k++) {
  224. sb.append(exceptions[k].getName());
  225. if (k < (exceptions.length - 1))
  226. sb.append(",");
  227. }
  228. }
  229. return sb.toString();
  230. } catch (Exception e) {
  231. return "<" + e + ">";
  232. }
  233. }
  234. /**
  235. * Invokes the underlying method represented by this <code>Method</code>
  236. * object, on the specified object with the specified parameters.
  237. * Individual parameters are automatically unwrapped to match
  238. * primitive formal parameters, and both primitive and reference
  239. * parameters are subject to method invocation conversions as
  240. * necessary.
  241. *
  242. * <p>If the underlying method is static, then the specified <code>obj</code>
  243. * argument is ignored. It may be null.
  244. *
  245. * <p>If the number of formal parameters required by the underlying method is
  246. * 0, the supplied <code>args</code> array may be of length 0 or null.
  247. *
  248. * <p>If the underlying method is an instance method, it is invoked
  249. * using dynamic method lookup as documented in The Java Language
  250. * Specification, Second Edition, section 15.12.4.4; in particular,
  251. * overriding based on the runtime type of the target object will occur.
  252. *
  253. * <p>If the underlying method is static, the class that declared
  254. * the method is initialized if it has not already been initialized.
  255. *
  256. * <p>If the method completes normally, the value it returns is
  257. * returned to the caller of invoke; if the value has a primitive
  258. * type, it is first appropriately wrapped in an object. If the
  259. * underlying method return type is void, the invocation returns
  260. * null.
  261. *
  262. * @param obj the object the underlying method is invoked from
  263. * @param args the arguments used for the method call
  264. * @return the result of dispatching the method represented by
  265. * this object on <code>obj</code> with parameters
  266. * <code>args</code>
  267. *
  268. * @exception IllegalAccessException if this <code>Method</code> object
  269. * enforces Java language access control and the underlying
  270. * method is inaccessible.
  271. * @exception IllegalArgumentException if the method is an
  272. * instance method and the specified object argument
  273. * is not an instance of the class or interface
  274. * declaring the underlying method (or of a subclass
  275. * or implementor thereof); if the number of actual
  276. * and formal parameters differ; if an unwrapping
  277. * conversion for primitive arguments fails; or if,
  278. * after possible unwrapping, a parameter value
  279. * cannot be converted to the corresponding formal
  280. * parameter type by a method invocation conversion.
  281. * @exception InvocationTargetException if the underlying method
  282. * throws an exception.
  283. * @exception NullPointerException if the specified object is null
  284. * and the method is an instance method.
  285. * @exception ExceptionInInitializerError if the initialization
  286. * provoked by this method fails.
  287. */
  288. public Object invoke(Object obj, Object[] args)
  289. throws IllegalAccessException, IllegalArgumentException,
  290. InvocationTargetException
  291. {
  292. if (!override) {
  293. if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
  294. Class caller = Reflection.getCallerClass(1);
  295. Class targetClass = ((obj == null || !Modifier.isProtected(modifiers))
  296. ? clazz
  297. : obj.getClass());
  298. if (securityCheckCache != caller ||
  299. targetClass != securityCheckTargetClassCache) {
  300. Reflection.ensureMemberAccess(caller, clazz, obj, modifiers);
  301. securityCheckCache = caller;
  302. securityCheckTargetClassCache = targetClass;
  303. }
  304. }
  305. }
  306. if (methodAccessor == null) acquireMethodAccessor();
  307. return methodAccessor.invoke(obj, args);
  308. }
  309. // NOTE that there is no synchronization used here. It is correct
  310. // (though not efficient) to generate more than one MethodAccessor
  311. // for a given Method. However, avoiding synchronization will
  312. // probably make the implementation more scalable.
  313. private void acquireMethodAccessor() {
  314. // First check to see if one has been created yet, and take it
  315. // if so
  316. MethodAccessor tmp = null;
  317. if (root != null) tmp = root.getMethodAccessor();
  318. if (tmp != null) {
  319. methodAccessor = tmp;
  320. return;
  321. }
  322. // Otherwise fabricate one and propagate it up to the root
  323. tmp = reflectionFactory.newMethodAccessor(this);
  324. setMethodAccessor(tmp);
  325. }
  326. // Returns MethodAccessor for this Method object, not looking up
  327. // the chain to the root
  328. MethodAccessor getMethodAccessor() {
  329. return methodAccessor;
  330. }
  331. // Sets the MethodAccessor for this Method object and
  332. // (recursively) its root
  333. void setMethodAccessor(MethodAccessor accessor) {
  334. methodAccessor = accessor;
  335. // Propagate up
  336. if (root != null) {
  337. root.setMethodAccessor(accessor);
  338. }
  339. }
  340. /*
  341. * Avoid clone()
  342. */
  343. static Class[] copy(Class[] in) {
  344. int l = in.length;
  345. if (l == 0)
  346. return in;
  347. Class[] out = new Class[l];
  348. for (int i = 0; i < l; i++)
  349. out[i] = in[i];
  350. return out;
  351. }
  352. }