| GNU Classpath (0.95) | |
| Frames | No Frames |
1: /* Class.java -- Representation of a Java class. 2: Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006 3: Free Software Foundation 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: package java.lang; 40: 41: import gnu.classpath.VMStackWalker; 42: import gnu.java.lang.reflect.ClassSignatureParser; 43: 44: import java.io.InputStream; 45: import java.io.Serializable; 46: import java.lang.annotation.Annotation; 47: import java.lang.annotation.Inherited; 48: import java.lang.reflect.AccessibleObject; 49: import java.lang.reflect.AnnotatedElement; 50: import java.lang.reflect.Constructor; 51: import java.lang.reflect.Field; 52: import java.lang.reflect.GenericDeclaration; 53: import java.lang.reflect.InvocationTargetException; 54: import java.lang.reflect.Member; 55: import java.lang.reflect.Method; 56: import java.lang.reflect.Modifier; 57: import java.lang.reflect.Type; 58: import java.lang.reflect.TypeVariable; 59: import java.net.URL; 60: import java.security.AccessController; 61: import java.security.AllPermission; 62: import java.security.Permissions; 63: import java.security.PrivilegedAction; 64: import java.security.ProtectionDomain; 65: import java.util.ArrayList; 66: import java.util.Arrays; 67: import java.util.Collection; 68: import java.util.HashMap; 69: import java.util.HashSet; 70: 71: 72: /** 73: * A Class represents a Java type. There will never be multiple Class 74: * objects with identical names and ClassLoaders. Primitive types, array 75: * types, and void also have a Class object. 76: * 77: * <p>Arrays with identical type and number of dimensions share the same class. 78: * The array class ClassLoader is the same as the ClassLoader of the element 79: * type of the array (which can be null to indicate the bootstrap classloader). 80: * The name of an array class is <code>[<signature format>;</code>. 81: * <p> For example, 82: * String[]'s class is <code>[Ljava.lang.String;</code>. boolean, byte, 83: * short, char, int, long, float and double have the "type name" of 84: * Z,B,S,C,I,J,F,D for the purposes of array classes. If it's a 85: * multidimensioned array, the same principle applies: 86: * <code>int[][][]</code> == <code>[[[I</code>. 87: * 88: * <p>There is no public constructor - Class objects are obtained only through 89: * the virtual machine, as defined in ClassLoaders. 90: * 91: * @serialData Class objects serialize specially: 92: * <code>TC_CLASS ClassDescriptor</code>. For more serialization information, 93: * see {@link ObjectStreamClass}. 94: * 95: * @author John Keiser 96: * @author Eric Blake (ebb9@email.byu.edu) 97: * @author Tom Tromey (tromey@redhat.com) 98: * @author Andrew John Hughes (gnu_andrew@member.fsf.org) 99: * @since 1.0 100: * @see ClassLoader 101: */ 102: public final class Class<T> 103: implements Serializable, Type, AnnotatedElement, GenericDeclaration 104: { 105: /** 106: * Compatible with JDK 1.0+. 107: */ 108: private static final long serialVersionUID = 3206093459760846163L; 109: 110: /** 111: * Flag indicating a synthetic member. 112: * Note that this duplicates a constant in Modifier. 113: */ 114: private static final int SYNTHETIC = 0x1000; 115: 116: /** 117: * Flag indiciating an annotation class. 118: */ 119: private static final int ANNOTATION = 0x2000; 120: 121: /** 122: * Flag indicating an enum constant or an enum class. 123: * Note that this duplicates a constant in Modifier. 124: */ 125: private static final int ENUM = 0x4000; 126: 127: /** The class signers. */ 128: private Object[] signers = null; 129: /** The class protection domain. */ 130: private final transient ProtectionDomain pd; 131: 132: /* We use an inner class, so that Class doesn't have a static initializer */ 133: private static final class StaticData 134: { 135: static final ProtectionDomain unknownProtectionDomain; 136: 137: static 138: { 139: Permissions permissions = new Permissions(); 140: permissions.add(new AllPermission()); 141: unknownProtectionDomain = new ProtectionDomain(null, permissions); 142: } 143: } 144: 145: final transient Object vmdata; 146: 147: /** newInstance() caches the default constructor */ 148: private transient Constructor<T> constructor; 149: 150: /** 151: * Class is non-instantiable from Java code; only the VM can create 152: * instances of this class. 153: */ 154: Class(Object vmdata) 155: { 156: this(vmdata, null); 157: } 158: 159: Class(Object vmdata, ProtectionDomain pd) 160: { 161: this.vmdata = vmdata; 162: // If the VM didn't supply a protection domain and the class is an array, 163: // we "inherit" the protection domain from the component type class. This 164: // saves the VM from having to worry about protection domains for array 165: // classes. 166: if (pd == null && isArray()) 167: this.pd = getComponentType().pd; 168: else 169: this.pd = pd; 170: } 171: 172: /** 173: * Use the classloader of the current class to load, link, and initialize 174: * a class. This is equivalent to your code calling 175: * <code>Class.forName(name, true, getClass().getClassLoader())</code>. 176: * 177: * @param name the name of the class to find 178: * @return the Class object representing the class 179: * @throws ClassNotFoundException if the class was not found by the 180: * classloader 181: * @throws LinkageError if linking the class fails 182: * @throws ExceptionInInitializerError if the class loads, but an exception 183: * occurs during initialization 184: */ 185: public static Class<?> forName(String name) throws ClassNotFoundException 186: { 187: return VMClass.forName(name, true, VMStackWalker.getCallingClassLoader()); 188: } 189: 190: /** 191: * Use the specified classloader to load and link a class. If the loader 192: * is null, this uses the bootstrap class loader (provide the security 193: * check succeeds). Unfortunately, this method cannot be used to obtain 194: * the Class objects for primitive types or for void, you have to use 195: * the fields in the appropriate java.lang wrapper classes. 196: * 197: * <p>Calls <code>classloader.loadclass(name, initialize)</code>. 198: * 199: * @param name the name of the class to find 200: * @param initialize whether or not to initialize the class at this time 201: * @param classloader the classloader to use to find the class; null means 202: * to use the bootstrap class loader 203: * 204: * @return the class object for the given class 205: * 206: * @throws ClassNotFoundException if the class was not found by the 207: * classloader 208: * @throws LinkageError if linking the class fails 209: * @throws ExceptionInInitializerError if the class loads, but an exception 210: * occurs during initialization 211: * @throws SecurityException if the <code>classloader</code> argument 212: * is <code>null</code> and the caller does not have the 213: * <code>RuntimePermission("getClassLoader")</code> permission 214: * @see ClassLoader 215: * @since 1.2 216: */ 217: public static Class<?> forName(String name, boolean initialize, 218: ClassLoader classloader) 219: throws ClassNotFoundException 220: { 221: if (classloader == null) 222: { 223: // Check if we may access the bootstrap classloader 224: SecurityManager sm = SecurityManager.current; 225: if (sm != null) 226: { 227: // Get the calling classloader 228: ClassLoader cl = VMStackWalker.getCallingClassLoader(); 229: if (cl != null) 230: sm.checkPermission(new RuntimePermission("getClassLoader")); 231: } 232: } 233: return (Class<?>) VMClass.forName(name, initialize, classloader); 234: } 235: 236: /** 237: * Get all the public member classes and interfaces declared in this 238: * class or inherited from superclasses. This returns an array of length 239: * 0 if there are no member classes, including for primitive types. A 240: * security check may be performed, with 241: * <code>checkMemberAccess(this, Member.PUBLIC)</code> as well as 242: * <code>checkPackageAccess</code> both having to succeed. 243: * 244: * @return all public member classes in this class 245: * @throws SecurityException if the security check fails 246: * @since 1.1 247: */ 248: public Class<?>[] getClasses() 249: { 250: memberAccessCheck(Member.PUBLIC); 251: return internalGetClasses(); 252: } 253: 254: /** 255: * Like <code>getClasses()</code> but without the security checks. 256: */ 257: private Class<?>[] internalGetClasses() 258: { 259: ArrayList<Class> list = new ArrayList<Class>(); 260: list.addAll(Arrays.asList(getDeclaredClasses(true))); 261: Class superClass = getSuperclass(); 262: if (superClass != null) 263: list.addAll(Arrays.asList(superClass.internalGetClasses())); 264: return list.toArray(new Class<?>[list.size()]); 265: } 266: 267: /** 268: * Get the ClassLoader that loaded this class. If the class was loaded 269: * by the bootstrap classloader, this method will return null. 270: * If there is a security manager, and the caller's class loader is not 271: * an ancestor of the requested one, a security check of 272: * <code>RuntimePermission("getClassLoader")</code> 273: * must first succeed. Primitive types and void return null. 274: * 275: * @return the ClassLoader that loaded this class 276: * @throws SecurityException if the security check fails 277: * @see ClassLoader 278: * @see RuntimePermission 279: */ 280: public ClassLoader getClassLoader() 281: { 282: if (isPrimitive()) 283: return null; 284: 285: ClassLoader loader = VMClass.getClassLoader(this); 286: // Check if we may get the classloader 287: SecurityManager sm = SecurityManager.current; 288: if (loader != null && sm != null) 289: { 290: // Get the calling classloader 291: ClassLoader cl = VMStackWalker.getCallingClassLoader(); 292: if (cl != null && !cl.isAncestorOf(loader)) 293: sm.checkPermission(new RuntimePermission("getClassLoader")); 294: } 295: return loader; 296: } 297: 298: /** 299: * If this is an array, get the Class representing the type of array. 300: * Examples: "[[Ljava.lang.String;" would return "[Ljava.lang.String;", and 301: * calling getComponentType on that would give "java.lang.String". If 302: * this is not an array, returns null. 303: * 304: * @return the array type of this class, or null 305: * @see Array 306: * @since 1.1 307: */ 308: public Class<?> getComponentType() 309: { 310: return VMClass.getComponentType (this); 311: } 312: 313: /** 314: * Get a public constructor declared in this class. If the constructor takes 315: * no argument, an array of zero elements and null are equivalent for the 316: * types argument. A security check may be performed, with 317: * <code>checkMemberAccess(this, Member.PUBLIC)</code> as well as 318: * <code>checkPackageAccess</code> both having to succeed. 319: * 320: * @param types the type of each parameter 321: * @return the constructor 322: * @throws NoSuchMethodException if the constructor does not exist 323: * @throws SecurityException if the security check fails 324: * @see #getConstructors() 325: * @since 1.1 326: */ 327: public Constructor<T> getConstructor(Class<?>... types) 328: throws NoSuchMethodException 329: { 330: memberAccessCheck(Member.PUBLIC); 331: Constructor[] constructors = getDeclaredConstructors(true); 332: for (int i = 0; i < constructors.length; i++) 333: { 334: Constructor constructor = constructors[i]; 335: if (matchParameters(types, constructor.getParameterTypes())) 336: return constructor; 337: } 338: throw new NoSuchMethodException(); 339: } 340: 341: /** 342: * Get all the public constructors of this class. This returns an array of 343: * length 0 if there are no constructors, including for primitive types, 344: * arrays, and interfaces. It does, however, include the default 345: * constructor if one was supplied by the compiler. A security check may 346: * be performed, with <code>checkMemberAccess(this, Member.PUBLIC)</code> 347: * as well as <code>checkPackageAccess</code> both having to succeed. 348: * 349: * @return all public constructors in this class 350: * @throws SecurityException if the security check fails 351: * @since 1.1 352: */ 353: public Constructor<?>[] getConstructors() 354: { 355: memberAccessCheck(Member.PUBLIC); 356: return getDeclaredConstructors(true); 357: } 358: 359: /** 360: * Get a constructor declared in this class. If the constructor takes no 361: * argument, an array of zero elements and null are equivalent for the 362: * types argument. A security check may be performed, with 363: * <code>checkMemberAccess(this, Member.DECLARED)</code> as well as 364: * <code>checkPackageAccess</code> both having to succeed. 365: * 366: * @param types the type of each parameter 367: * @return the constructor 368: * @throws NoSuchMethodException if the constructor does not exist 369: * @throws SecurityException if the security check fails 370: * @see #getDeclaredConstructors() 371: * @since 1.1 372: */ 373: public Constructor<T> getDeclaredConstructor(Class<?>... types) 374: throws NoSuchMethodException 375: { 376: memberAccessCheck(Member.DECLARED); 377: Constructor[] constructors = getDeclaredConstructors(false); 378: for (int i = 0; i < constructors.length; i++) 379: { 380: Constructor constructor = constructors[i]; 381: if (matchParameters(types, constructor.getParameterTypes())) 382: return constructor; 383: } 384: throw new NoSuchMethodException(); 385: } 386: 387: /** 388: * Get all the declared member classes and interfaces in this class, but 389: * not those inherited from superclasses. This returns an array of length 390: * 0 if there are no member classes, including for primitive types. A 391: * security check may be performed, with 392: * <code>checkMemberAccess(this, Member.DECLARED)</code> as well as 393: * <code>checkPackageAccess</code> both having to succeed. 394: * 395: * @return all declared member classes in this class 396: * @throws SecurityException if the security check fails 397: * @since 1.1 398: */ 399: public Class<?>[] getDeclaredClasses() 400: { 401: memberAccessCheck(Member.DECLARED); 402: return getDeclaredClasses(false); 403: } 404: 405: Class<?>[] getDeclaredClasses (boolean publicOnly) 406: { 407: return VMClass.getDeclaredClasses (this, publicOnly); 408: } 409: 410: /** 411: * Get all the declared constructors of this class. This returns an array of 412: * length 0 if there are no constructors, including for primitive types, 413: * arrays, and interfaces. It does, however, include the default 414: * constructor if one was supplied by the compiler. A security check may 415: * be performed, with <code>checkMemberAccess(this, Member.DECLARED)</code> 416: * as well as <code>checkPackageAccess</code> both having to succeed. 417: * 418: * @return all constructors in this class 419: * @throws SecurityException if the security check fails 420: * @since 1.1 421: */ 422: public Constructor<?>[] getDeclaredConstructors() 423: { 424: memberAccessCheck(Member.DECLARED); 425: return getDeclaredConstructors(false); 426: } 427: 428: Constructor<?>[] getDeclaredConstructors (boolean publicOnly) 429: { 430: return VMClass.getDeclaredConstructors (this, publicOnly); 431: } 432: 433: /** 434: * Get a field declared in this class, where name is its simple name. The 435: * implicit length field of arrays is not available. A security check may 436: * be performed, with <code>checkMemberAccess(this, Member.DECLARED)</code> 437: * as well as <code>checkPackageAccess</code> both having to succeed. 438: * 439: * @param name the name of the field 440: * @return the field 441: * @throws NoSuchFieldException if the field does not exist 442: * @throws SecurityException if the security check fails 443: * @see #getDeclaredFields() 444: * @since 1.1 445: */ 446: public Field getDeclaredField(String name) throws NoSuchFieldException 447: { 448: memberAccessCheck(Member.DECLARED); 449: Field[] fields = getDeclaredFields(false); 450: for (int i = 0; i < fields.length; i++) 451: { 452: if (fields[i].getName().equals(name)) 453: return fields[i]; 454: } 455: throw new NoSuchFieldException(); 456: } 457: 458: /** 459: * Get all the declared fields in this class, but not those inherited from 460: * superclasses. This returns an array of length 0 if there are no fields, 461: * including for primitive types. This does not return the implicit length 462: * field of arrays. A security check may be performed, with 463: * <code>checkMemberAccess(this, Member.DECLARED)</code> as well as 464: * <code>checkPackageAccess</code> both having to succeed. 465: * 466: * @return all declared fields in this class 467: * @throws SecurityException if the security check fails 468: * @since 1.1 469: */ 470: public Field[] getDeclaredFields() 471: { 472: memberAccessCheck(Member.DECLARED); 473: return getDeclaredFields(false); 474: } 475: 476: Field[] getDeclaredFields (boolean publicOnly) 477: { 478: return VMClass.getDeclaredFields (this, publicOnly); 479: } 480: 481: /** 482: * Get a method declared in this class, where name is its simple name. The 483: * implicit methods of Object are not available from arrays or interfaces. 484: * Constructors (named "<init>" in the class file) and class initializers 485: * (name "<clinit>") are not available. The Virtual Machine allows 486: * multiple methods with the same signature but differing return types; in 487: * such a case the most specific return types are favored, then the final 488: * choice is arbitrary. If the method takes no argument, an array of zero 489: * elements and null are equivalent for the types argument. A security 490: * check may be performed, with 491: * <code>checkMemberAccess(this, Member.DECLARED)</code> as well as 492: * <code>checkPackageAccess</code> both having to succeed. 493: * 494: * @param methodName the name of the method 495: * @param types the type of each parameter 496: * @return the method 497: * @throws NoSuchMethodException if the method does not exist 498: * @throws SecurityException if the security check fails 499: * @see #getDeclaredMethods() 500: * @since 1.1 501: */ 502: public Method getDeclaredMethod(String methodName, Class<?>... types) 503: throws NoSuchMethodException 504: { 505: memberAccessCheck(Member.DECLARED); 506: Method match = matchMethod(getDeclaredMethods(false), methodName, types); 507: if (match == null) 508: throw new NoSuchMethodException(methodName); 509: return match; 510: } 511: 512: /** 513: * Get all the declared methods in this class, but not those inherited from 514: * superclasses. This returns an array of length 0 if there are no methods, 515: * including for primitive types. This does include the implicit methods of 516: * arrays and interfaces which mirror methods of Object, nor does it 517: * include constructors or the class initialization methods. The Virtual 518: * Machine allows multiple methods with the same signature but differing 519: * return types; all such methods are in the returned array. A security 520: * check may be performed, with 521: * <code>checkMemberAccess(this, Member.DECLARED)</code> as well as 522: * <code>checkPackageAccess</code> both having to succeed. 523: * 524: * @return all declared methods in this class 525: * @throws SecurityException if the security check fails 526: * @since 1.1 527: */ 528: public Method[] getDeclaredMethods() 529: { 530: memberAccessCheck(Member.DECLARED); 531: return getDeclaredMethods(false); 532: } 533: 534: Method[] getDeclaredMethods (boolean publicOnly) 535: { 536: return VMClass.getDeclaredMethods (this, publicOnly); 537: } 538: 539: /** 540: * If this is a nested or inner class, return the class that declared it. 541: * If not, return null. 542: * 543: * @return the declaring class of this class 544: * @since 1.1 545: */ 546: public Class<?> getDeclaringClass() 547: { 548: return VMClass.getDeclaringClass (this); 549: } 550: 551: /** 552: * Get a public field declared or inherited in this class, where name is 553: * its simple name. If the class contains multiple accessible fields by 554: * that name, an arbitrary one is returned. The implicit length field of 555: * arrays is not available. A security check may be performed, with 556: * <code>checkMemberAccess(this, Member.PUBLIC)</code> as well as 557: * <code>checkPackageAccess</code> both having to succeed. 558: * 559: * @param fieldName the name of the field 560: * @return the field 561: * @throws NoSuchFieldException if the field does not exist 562: * @throws SecurityException if the security check fails 563: * @see #getFields() 564: * @since 1.1 565: */ 566: public Field getField(String fieldName) 567: throws NoSuchFieldException 568: { 569: memberAccessCheck(Member.PUBLIC); 570: Field field = internalGetField(fieldName); 571: if (field == null) 572: throw new NoSuchFieldException(fieldName); 573: return field; 574: } 575: 576: /** 577: * Get all the public fields declared in this class or inherited from 578: * superclasses. This returns an array of length 0 if there are no fields, 579: * including for primitive types. This does not return the implicit length 580: * field of arrays. A security check may be performed, with 581: * <code>checkMemberAccess(this, Member.PUBLIC)</code> as well as 582: * <code>checkPackageAccess</code> both having to succeed. 583: * 584: * @return all public fields in this class 585: * @throws SecurityException if the security check fails 586: * @since 1.1 587: */ 588: public Field[] getFields() 589: { 590: memberAccessCheck(Member.PUBLIC); 591: return internalGetFields(); 592: } 593: 594: /** 595: * Like <code>getFields()</code> but without the security checks. 596: */ 597: private Field[] internalGetFields() 598: { 599: HashSet<Field> set = new HashSet<Field>(); 600: set.addAll(Arrays.asList(getDeclaredFields(true))); 601: Class[] interfaces = getInterfaces(); 602: for (int i = 0; i < interfaces.length; i++) 603: set.addAll(Arrays.asList(interfaces[i].internalGetFields())); 604: Class superClass = getSuperclass(); 605: if (superClass != null) 606: set.addAll(Arrays.asList(superClass.internalGetFields())); 607: return set.toArray(new Field[set.size()]); 608: } 609: 610: /** 611: * Returns the <code>Package</code> in which this class is defined 612: * Returns null when this information is not available from the 613: * classloader of this class. 614: * 615: * @return the package for this class, if it is available 616: * @since 1.2 617: */ 618: public Package getPackage() 619: { 620: ClassLoader cl = getClassLoader(); 621: if (cl != null) 622: return cl.getPackage(getPackagePortion(getName())); 623: else 624: return VMClassLoader.getPackage(getPackagePortion(getName())); 625: } 626: 627: /** 628: * Get the interfaces this class <em>directly</em> implements, in the 629: * order that they were declared. This returns an empty array, not null, 630: * for Object, primitives, void, and classes or interfaces with no direct 631: * superinterface. Array types return Cloneable and Serializable. 632: * 633: * @return the interfaces this class directly implements 634: */ 635: public Class<?>[] getInterfaces() 636: { 637: return VMClass.getInterfaces (this); 638: } 639: 640: private static final class MethodKey 641: { 642: private String name; 643: private Class[] params; 644: private Class returnType; 645: private int hash; 646: 647: MethodKey(Method m) 648: { 649: name = m.getName(); 650: params = m.getParameterTypes(); 651: returnType = m.getReturnType(); 652: hash = name.hashCode() ^ returnType.hashCode(); 653: for(int i = 0; i < params.length; i++) 654: { 655: hash ^= params[i].hashCode(); 656: } 657: } 658: 659: public boolean equals(Object o) 660: { 661: if (o instanceof MethodKey) 662: { 663: MethodKey m = (MethodKey) o; 664: if (m.name.equals(name) && m.params.length == params.length 665: && m.returnType == returnType) 666: { 667: for (int i = 0; i < params.length; i++) 668: { 669: if (m.params[i] != params[i]) 670: return false; 671: } 672: return true; 673: } 674: } 675: return false; 676: } 677: 678: public int hashCode() 679: { 680: return hash; 681: } 682: } 683: 684: /** 685: * Get a public method declared or inherited in this class, where name is 686: * its simple name. The implicit methods of Object are not available from 687: * interfaces. Constructors (named "<init>" in the class file) and class 688: * initializers (name "<clinit>") are not available. The Virtual 689: * Machine allows multiple methods with the same signature but differing 690: * return types, and the class can inherit multiple methods of the same 691: * return type; in such a case the most specific return types are favored, 692: * then the final choice is arbitrary. If the method takes no argument, an 693: * array of zero elements and null are equivalent for the types argument. 694: * A security check may be performed, with 695: * <code>checkMemberAccess(this, Member.PUBLIC)</code> as well as 696: * <code>checkPackageAccess</code> both having to succeed. 697: * 698: * @param methodName the name of the method 699: * @param types the type of each parameter 700: * @return the method 701: * @throws NoSuchMethodException if the method does not exist 702: * @throws SecurityException if the security check fails 703: * @see #getMethods() 704: * @since 1.1 705: */ 706: public Method getMethod(String methodName, Class<?>... types) 707: throws NoSuchMethodException 708: { 709: memberAccessCheck(Member.PUBLIC); 710: Method method = internalGetMethod(methodName, types); 711: if (method == null) 712: throw new NoSuchMethodException(methodName); 713: return method; 714: } 715: 716: /** 717: * Like <code>getMethod(String,Class[])</code> but without the security 718: * checks and returns null instead of throwing NoSuchMethodException. 719: */ 720: private Method internalGetMethod(String methodName, Class[] args) 721: { 722: Method match = matchMethod(getDeclaredMethods(true), methodName, args); 723: if (match != null) 724: return match; 725: Class superClass = getSuperclass(); 726: if (superClass != null) 727: { 728: match = superClass.internalGetMethod(methodName, args); 729: if(match != null) 730: return match; 731: } 732: Class[] interfaces = getInterfaces(); 733: for (int i = 0; i < interfaces.length; i++) 734: { 735: match = interfaces[i].internalGetMethod(methodName, args); 736: if (match != null) 737: return match; 738: } 739: return null; 740: } 741: 742: /** 743: * Find the best matching method in <code>list</code> according to 744: * the definition of ``best matching'' used by <code>getMethod()</code> 745: * 746: * <p> 747: * Returns the method if any, otherwise <code>null</code>. 748: * 749: * @param list List of methods to search 750: * @param name Name of method 751: * @param args Method parameter types 752: * @see #getMethod(String, Class[]) 753: */ 754: private static Method matchMethod(Method[] list, String name, Class[] args) 755: { 756: Method match = null; 757: for (int i = 0; i < list.length; i++) 758: { 759: Method method = list[i]; 760: if (!method.getName().equals(name)) 761: continue; 762: if (!matchParameters(args, method.getParameterTypes())) 763: continue; 764: if (match == null 765: || match.getReturnType().isAssignableFrom(method.getReturnType())) 766: match = method; 767: } 768: return match; 769: } 770: 771: /** 772: * Check for an exact match between parameter type lists. 773: * Either list may be <code>null</code> to mean a list of 774: * length zero. 775: */ 776: private static boolean matchParameters(Class[] types1, Class[] types2) 777: { 778: if (types1 == null) 779: return types2 == null || types2.length == 0; 780: if (types2 == null) 781: return types1 == null || types1.length == 0; 782: if (types1.length != types2.length) 783: return false; 784: for (int i = 0; i < types1.length; i++) 785: { 786: if (types1[i] != types2[i]) 787: return false; 788: } 789: return true; 790: } 791: 792: /** 793: * Get all the public methods declared in this class or inherited from 794: * superclasses. This returns an array of length 0 if there are no methods, 795: * including for primitive types. This does not include the implicit 796: * methods of interfaces which mirror methods of Object, nor does it 797: * include constructors or the class initialization methods. The Virtual 798: * Machine allows multiple methods with the same signature but differing 799: * return types; all such methods are in the returned array. A security 800: * check may be performed, with 801: * <code>checkMemberAccess(this, Member.PUBLIC)</code> as well as 802: * <code>checkPackageAccess</code> both having to succeed. 803: * 804: * @return all public methods in this class 805: * @throws SecurityException if the security check fails 806: * @since 1.1 807: */ 808: public Method[] getMethods() 809: { 810: memberAccessCheck(Member.PUBLIC); 811: // NOTE the API docs claim that no methods are returned for arrays, 812: // but Sun's implementation *does* return the public methods of Object 813: // (as would be expected), so we follow their implementation instead 814: // of their documentation. 815: return internalGetMethods(); 816: } 817: 818: /** 819: * Like <code>getMethods()</code> but without the security checks. 820: */ 821: private Method[] internalGetMethods() 822: { 823: HashMap<MethodKey,Method> map = new HashMap<MethodKey,Method>(); 824: Method[] methods; 825: Class[] interfaces = getInterfaces(); 826: for(int i = 0; i < interfaces.length; i++) 827: { 828: methods = interfaces[i].internalGetMethods(); 829: for(int j = 0; j < methods.length; j++) 830: { 831: map.put(new MethodKey(methods[j]), methods[j]); 832: } 833: } 834: Class superClass = getSuperclass(); 835: if(superClass != null) 836: { 837: methods = superClass.internalGetMethods(); 838: for(int i = 0; i < methods.length; i++) 839: { 840: map.put(new MethodKey(methods[i]), methods[i]); 841: } 842: } 843: methods = getDeclaredMethods(true); 844: for(int i = 0; i < methods.length; i++) 845: { 846: map.put(new MethodKey(methods[i]), methods[i]); 847: } 848: return map.values().toArray(new Method[map.size()]); 849: } 850: 851: /** 852: * Get the modifiers of this class. These can be decoded using Modifier, 853: * and is limited to one of public, protected, or private, and any of 854: * final, static, abstract, or interface. An array class has the same 855: * public, protected, or private modifier as its component type, and is 856: * marked final but not an interface. Primitive types and void are marked 857: * public and final, but not an interface. 858: * 859: * @return the modifiers of this class 860: * @see Modifier 861: * @since 1.1 862: */ 863: public int getModifiers()