GNU Classpath (0.17) | ||
Frames | No Frames |
1: /* Class.java -- Representation of a Java class. 2: Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2005 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: 43: import java.io.InputStream; 44: import java.io.Serializable; 45: import java.lang.reflect.Constructor; 46: import java.lang.reflect.Field; 47: import java.lang.reflect.InvocationTargetException; 48: import java.lang.reflect.Member; 49: import java.lang.reflect.Method; 50: import java.lang.reflect.Modifier; 51: import java.net.URL; 52: import java.security.AccessController; 53: import java.security.AllPermission; 54: import java.security.Permissions; 55: import java.security.PrivilegedAction; 56: import java.security.ProtectionDomain; 57: import java.util.ArrayList; 58: import java.util.Arrays; 59: import java.util.HashMap; 60: import java.util.HashSet; 61: 62: 63: /** 64: * A Class represents a Java type. There will never be multiple Class 65: * objects with identical names and ClassLoaders. Primitive types, array 66: * types, and void also have a Class object. 67: * 68: * <p>Arrays with identical type and number of dimensions share the same class. 69: * The array class ClassLoader is the same as the ClassLoader of the element 70: * type of the array (which can be null to indicate the bootstrap classloader). 71: * The name of an array class is <code>[<signature format>;</code>. 72: * <p> For example, 73: * String[]'s class is <code>[Ljava.lang.String;</code>. boolean, byte, 74: * short, char, int, long, float and double have the "type name" of 75: * Z,B,S,C,I,J,F,D for the purposes of array classes. If it's a 76: * multidimensioned array, the same principle applies: 77: * <code>int[][][]</code> == <code>[[[I</code>. 78: * 79: * <p>There is no public constructor - Class objects are obtained only through 80: * the virtual machine, as defined in ClassLoaders. 81: * 82: * @serialData Class objects serialize specially: 83: * <code>TC_CLASS ClassDescriptor</code>. For more serialization information, 84: * see {@link ObjectStreamClass}. 85: * 86: * @author John Keiser 87: * @author Eric Blake (ebb9@email.byu.edu) 88: * @author Tom Tromey (tromey@cygnus.com) 89: * @since 1.0 90: * @see ClassLoader 91: */ 92: public final class Class implements Serializable 93: { 94: /** 95: * Compatible with JDK 1.0+. 96: */ 97: private static final long serialVersionUID = 3206093459760846163L; 98: 99: /** The class signers. */ 100: private Object[] signers = null; 101: /** The class protection domain. */ 102: private final ProtectionDomain pd; 103: 104: /* We use an inner class, so that Class doesn't have a static initializer */ 105: private static final class StaticData 106: { 107: static final ProtectionDomain unknownProtectionDomain; 108: 109: static 110: { 111: Permissions permissions = new Permissions(); 112: permissions.add(new AllPermission()); 113: unknownProtectionDomain = new ProtectionDomain(null, permissions); 114: } 115: } 116: 117: final transient Object vmdata; 118: 119: /** newInstance() caches the default constructor */ 120: private transient Constructor constructor; 121: 122: /** 123: * Class is non-instantiable from Java code; only the VM can create 124: * instances of this class. 125: */ 126: Class(Object vmdata) 127: { 128: this(vmdata, null); 129: } 130: 131: Class(Object vmdata, ProtectionDomain pd) 132: { 133: this.vmdata = vmdata; 134: // If the VM didn't supply a protection domain and the class is an array, 135: // we "inherit" the protection domain from the component type class. This 136: // saves the VM from having to worry about protection domains for array 137: // classes. 138: if (pd == null && isArray()) 139: this.pd = getComponentType().pd; 140: else 141: this.pd = pd; 142: } 143: 144: /** 145: * Use the classloader of the current class to load, link, and initialize 146: * a class. This is equivalent to your code calling 147: * <code>Class.forName(name, true, getClass().getClassLoader())</code>. 148: * 149: * @param name the name of the class to find 150: * @return the Class object representing the class 151: * @throws ClassNotFoundException if the class was not found by the 152: * classloader 153: * @throws LinkageError if linking the class fails 154: * @throws ExceptionInInitializerError if the class loads, but an exception 155: * occurs during initialization 156: */ 157: public static Class forName(String name) throws ClassNotFoundException 158: { 159: Class result = VMClass.forName (name); 160: if (result == null) 161: result = Class.forName(name, true, 162: VMStackWalker.getCallingClassLoader()); 163: return result; 164: } 165: 166: /** 167: * Use the specified classloader to load and link a class. If the loader 168: * is null, this uses the bootstrap class loader (provide the security 169: * check succeeds). Unfortunately, this method cannot be used to obtain 170: * the Class objects for primitive types or for void, you have to use 171: * the fields in the appropriate java.lang wrapper classes. 172: * 173: * <p>Calls <code>classloader.loadclass(name, initialize)</code>. 174: * 175: * @param name the name of the class to find 176: * @param initialize whether or not to initialize the class at this time 177: * @param classloader the classloader to use to find the class; null means 178: * to use the bootstrap class loader 179: * 180: * @return the class object for the given class 181: * 182: * @throws ClassNotFoundException if the class was not found by the 183: * classloader 184: * @throws LinkageError if linking the class fails 185: * @throws ExceptionInInitializerError if the class loads, but an exception 186: * occurs during initialization 187: * @throws SecurityException if the <code>classloader</code> argument 188: * is <code>null</code> and the caller does not have the 189: * <code>RuntimePermission("getClassLoader")</code> permission 190: * @see ClassLoader 191: * @since 1.2 192: */ 193: public static Class forName(String name, boolean initialize, 194: ClassLoader classloader) 195: throws ClassNotFoundException 196: { 197: if (classloader == null) 198: { 199: // Check if we may access the bootstrap classloader 200: SecurityManager sm = SecurityManager.current; 201: if (sm != null) 202: { 203: // Get the calling classloader 204: ClassLoader cl = VMStackWalker.getCallingClassLoader(); 205: if (cl != null) 206: sm.checkPermission(new RuntimePermission("getClassLoader")); 207: } 208: if (name.startsWith("[")) 209: return VMClass.loadArrayClass(name, null); 210: Class c = VMClassLoader.loadClass(name, true); 211: if (c != null) 212: { 213: if (initialize) 214: VMClass.initialize(c); 215: return c; 216: } 217: throw new ClassNotFoundException(name); 218: } 219: if (name.startsWith("[")) 220: return VMClass.loadArrayClass(name, classloader); 221: Class c = classloader.loadClass(name); 222: classloader.resolveClass(c); 223: if (initialize) 224: VMClass.initialize(c); 225: return c; 226: } 227: 228: /** 229: * Get all the public member classes and interfaces declared in this 230: * class or inherited from superclasses. This returns an array of length 231: * 0 if there are no member classes, including for primitive types. A 232: * security check may be performed, with 233: * <code>checkMemberAccess(this, Member.PUBLIC)</code> as well as 234: * <code>checkPackageAccess</code> both having to succeed. 235: * 236: * @return all public member classes in this class 237: * @throws SecurityException if the security check fails 238: * @since 1.1 239: */ 240: public Class[] getClasses() 241: { 242: memberAccessCheck(Member.PUBLIC); 243: return internalGetClasses(); 244: } 245: 246: /** 247: * Like <code>getClasses()</code> but without the security checks. 248: */ 249: private Class[] internalGetClasses() 250: { 251: ArrayList list = new ArrayList(); 252: list.addAll(Arrays.asList(getDeclaredClasses(true))); 253: Class superClass = getSuperclass(); 254: if (superClass != null) 255: list.addAll(Arrays.asList(superClass.internalGetClasses())); 256: return (Class[])list.toArray(new Class[list.size()]); 257: } 258: 259: /** 260: * Get the ClassLoader that loaded this class. If the class was loaded 261: * by the bootstrap classloader, this method will return null. 262: * If there is a security manager, and the caller's class loader is not 263: * an ancestor of the requested one, a security check of 264: * <code>RuntimePermission("getClassLoader")</code> 265: * must first succeed. Primitive types and void return null. 266: * 267: * @return the ClassLoader that loaded this class 268: * @throws SecurityException if the security check fails 269: * @see ClassLoader 270: * @see RuntimePermission 271: */ 272: public ClassLoader getClassLoader() 273: { 274: if (isPrimitive()) 275: return null; 276: 277: ClassLoader loader = VMClass.getClassLoader(this); 278: // Check if we may get the classloader 279: SecurityManager sm = SecurityManager.current; 280: if (sm != null) 281: { 282: // Get the calling classloader 283: ClassLoader cl = VMStackWalker.getCallingClassLoader(); 284: if (cl != null && !cl.isAncestorOf(loader)) 285: sm.checkPermission(new RuntimePermission("getClassLoader")); 286: } 287: return loader; 288: } 289: 290: /** 291: * If this is an array, get the Class representing the type of array. 292: * Examples: "[[Ljava.lang.String;" would return "[Ljava.lang.String;", and 293: * calling getComponentType on that would give "java.lang.String". If 294: * this is not an array, returns null. 295: * 296: * @return the array type of this class, or null 297: * @see Array 298: * @since 1.1 299: */ 300: public Class getComponentType() 301: { 302: return VMClass.getComponentType (this); 303: } 304: 305: /** 306: * Get a public constructor declared in this class. If the constructor takes 307: * no argument, an array of zero elements and null are equivalent for the 308: * types argument. A security check may be performed, with 309: * <code>checkMemberAccess(this, Member.PUBLIC)</code> as well as 310: * <code>checkPackageAccess</code> both having to succeed. 311: * 312: * @param types the type of each parameter 313: * @return the constructor 314: * @throws NoSuchMethodException if the constructor does not exist 315: * @throws SecurityException if the security check fails 316: * @see #getConstructors() 317: * @since 1.1 318: */ 319: public Constructor getConstructor(Class[] types) throws NoSuchMethodException 320: { 321: memberAccessCheck(Member.PUBLIC); 322: Constructor[] constructors = getDeclaredConstructors(true); 323: for (int i = 0; i < constructors.length; i++) 324: { 325: Constructor constructor = constructors[i]; 326: if (matchParameters(types, constructor.getParameterTypes())) 327: return constructor; 328: } 329: throw new NoSuchMethodException(); 330: } 331: 332: /** 333: * Get all the public constructors of this class. This returns an array of 334: * length 0 if there are no constructors, including for primitive types, 335: * arrays, and interfaces. It does, however, include the default 336: * constructor if one was supplied by the compiler. A security check may 337: * be performed, with <code>checkMemberAccess(this, Member.PUBLIC)</code> 338: * as well as <code>checkPackageAccess</code> both having to succeed. 339: * 340: * @return all public constructors in this class 341: * @throws SecurityException if the security check fails 342: * @since 1.1 343: */ 344: public Constructor[] getConstructors() 345: { 346: memberAccessCheck(Member.PUBLIC); 347: return getDeclaredConstructors(true); 348: } 349: 350: /** 351: * Get a constructor declared in this class. If the constructor takes no 352: * argument, an array of zero elements and null are equivalent for the 353: * types argument. A security check may be performed, with 354: * <code>checkMemberAccess(this, Member.DECLARED)</code> as well as 355: * <code>checkPackageAccess</code> both having to succeed. 356: * 357: * @param types the type of each parameter 358: * @return the constructor 359: * @throws NoSuchMethodException if the constructor does not exist 360: * @throws SecurityException if the security check fails 361: * @see #getDeclaredConstructors() 362: * @since 1.1 363: */ 364: public Constructor getDeclaredConstructor(Class[] types) 365: throws NoSuchMethodException 366: { 367: memberAccessCheck(Member.DECLARED); 368: Constructor[] constructors = getDeclaredConstructors(false); 369: for (int i = 0; i < constructors.length; i++) 370: { 371: Constructor constructor = constructors[i]; 372: if (matchParameters(types, constructor.getParameterTypes())) 373: return constructor; 374: } 375: throw new NoSuchMethodException(); 376: } 377: 378: /** 379: * Get all the declared member classes and interfaces in this class, but 380: * not those inherited from superclasses. This returns an array of length 381: * 0 if there are no member classes, including for primitive types. A 382: * security check may be performed, with 383: * <code>checkMemberAccess(this, Member.DECLARED)</code> as well as 384: * <code>checkPackageAccess</code> both having to succeed. 385: * 386: * @return all declared member classes in this class 387: * @throws SecurityException if the security check fails 388: * @since 1.1 389: */ 390: public Class[] getDeclaredClasses() 391: { 392: memberAccessCheck(Member.DECLARED); 393: return getDeclaredClasses(false); 394: } 395: 396: Class[] getDeclaredClasses (boolean publicOnly) 397: { 398: return VMClass.getDeclaredClasses (this, publicOnly); 399: } 400: 401: /** 402: * Get all the declared constructors of this class. This returns an array of 403: * length 0 if there are no constructors, including for primitive types, 404: * arrays, and interfaces. It does, however, include the default 405: * constructor if one was supplied by the compiler. A security check may 406: * be performed, with <code>checkMemberAccess(this, Member.DECLARED)</code> 407: * as well as <code>checkPackageAccess</code> both having to succeed. 408: * 409: * @return all constructors in this class 410: * @throws SecurityException if the security check fails 411: * @since 1.1 412: */ 413: public Constructor[] getDeclaredConstructors() 414: { 415: memberAccessCheck(Member.DECLARED); 416: return getDeclaredConstructors(false); 417: } 418: 419: Constructor[] getDeclaredConstructors (boolean publicOnly) 420: { 421: return VMClass.getDeclaredConstructors (this, publicOnly); 422: } 423: 424: /** 425: * Get a field declared in this class, where name is its simple name. The 426: * implicit length field of arrays is not available. A security check may 427: * be performed, with <code>checkMemberAccess(this, Member.DECLARED)</code> 428: * as well as <code>checkPackageAccess</code> both having to succeed. 429: * 430: * @param name the name of the field 431: * @return the field 432: * @throws NoSuchFieldException if the field does not exist 433: * @throws SecurityException if the security check fails 434: * @see #getDeclaredFields() 435: * @since 1.1 436: */ 437: public Field getDeclaredField(String name) throws NoSuchFieldException 438: { 439: memberAccessCheck(Member.DECLARED); 440: Field[] fields = getDeclaredFields(false); 441: for (int i = 0; i < fields.length; i++) 442: { 443: if (fields[i].getName().equals(name)) 444: return fields[i]; 445: } 446: throw new NoSuchFieldException(); 447: } 448: 449: /** 450: * Get all the declared fields in this class, but not those inherited from 451: * superclasses. This returns an array of length 0 if there are no fields, 452: * including for primitive types. This does not return the implicit length 453: * field of arrays. A security check may be performed, with 454: * <code>checkMemberAccess(this, Member.DECLARED)</code> as well as 455: * <code>checkPackageAccess</code> both having to succeed. 456: * 457: * @return all declared fields in this class 458: * @throws SecurityException if the security check fails 459: * @since 1.1 460: */ 461: public Field[] getDeclaredFields() 462: { 463: memberAccessCheck(Member.DECLARED); 464: return getDeclaredFields(false); 465: } 466: 467: Field[] getDeclaredFields (boolean publicOnly) 468: { 469: return VMClass.getDeclaredFields (this, publicOnly); 470: } 471: 472: /** 473: * Get a method declared in this class, where name is its simple name. The 474: * implicit methods of Object are not available from arrays or interfaces. 475: * Constructors (named "<init>" in the class file) and class initializers 476: * (name "<clinit>") are not available. The Virtual Machine allows 477: * multiple methods with the same signature but differing return types; in 478: * such a case the most specific return types are favored, then the final 479: * choice is arbitrary. If the method takes no argument, an array of zero 480: * elements and null are equivalent for the types argument. A security 481: * check may be performed, with 482: * <code>checkMemberAccess(this, Member.DECLARED)</code> as well as 483: * <code>checkPackageAccess</code> both having to succeed. 484: * 485: * @param methodName the name of the method 486: * @param types the type of each parameter 487: * @return the method 488: * @throws NoSuchMethodException if the method does not exist 489: * @throws SecurityException if the security check fails 490: * @see #getDeclaredMethods() 491: * @since 1.1 492: */ 493: public Method getDeclaredMethod(String methodName, Class[] types) 494: throws NoSuchMethodException 495: { 496: memberAccessCheck(Member.DECLARED); 497: Method match = matchMethod(getDeclaredMethods(false), methodName, types); 498: if (match == null) 499: throw new NoSuchMethodException(methodName); 500: return match; 501: } 502: 503: /** 504: * Get all the declared methods in this class, but not those inherited from 505: * superclasses. This returns an array of length 0 if there are no methods, 506: * including for primitive types. This does include the implicit methods of 507: * arrays and interfaces which mirror methods of Object, nor does it 508: * include constructors or the class initialization methods. The Virtual 509: * Machine allows multiple methods with the same signature but differing 510: * return types; all such methods are in the returned array. A security 511: * check may be performed, with 512: * <code>checkMemberAccess(this, Member.DECLARED)</code> as well as 513: * <code>checkPackageAccess</code> both having to succeed. 514: * 515: * @return all declared methods in this class 516: * @throws SecurityException if the security check fails 517: * @since 1.1 518: */ 519: public Method[] getDeclaredMethods() 520: { 521: memberAccessCheck(Member.DECLARED); 522: return getDeclaredMethods(false); 523: } 524: 525: Method[] getDeclaredMethods (boolean publicOnly) 526: { 527: return VMClass.getDeclaredMethods (this, publicOnly); 528: } 529: 530: /** 531: * If this is a nested or inner class, return the class that declared it. 532: * If not, return null. 533: * 534: * @return the declaring class of this class 535: * @since 1.1 536: */ 537: public Class getDeclaringClass() 538: { 539: return VMClass.getDeclaringClass (this); 540: } 541: 542: /** 543: * Get a public field declared or inherited in this class, where name is 544: * its simple name. If the class contains multiple accessible fields by 545: * that name, an arbitrary one is returned. The implicit length field of 546: * arrays is not available. A security check may be performed, with 547: * <code>checkMemberAccess(this, Member.PUBLIC)</code> as well as 548: * <code>checkPackageAccess</code> both having to succeed. 549: * 550: * @param fieldName the name of the field 551: * @return the field 552: * @throws NoSuchFieldException if the field does not exist 553: * @throws SecurityException if the security check fails 554: * @see #getFields() 555: * @since 1.1 556: */ 557: public Field getField(String fieldName) 558: throws NoSuchFieldException 559: { 560: memberAccessCheck(Member.PUBLIC); 561: Field field = internalGetField(fieldName); 562: if (field == null) 563: throw new NoSuchFieldException(fieldName); 564: return field; 565: } 566: 567: /** 568: * Get all the public fields declared in this class or inherited from 569: * superclasses. This returns an array of length 0 if there are no fields, 570: * including for primitive types. This does not return the implicit length 571: * field of arrays. A security check may be performed, with 572: * <code>checkMemberAccess(this, Member.PUBLIC)</code> as well as 573: * <code>checkPackageAccess</code> both having to succeed. 574: * 575: * @return all public fields in this class 576: * @throws SecurityException if the security check fails 577: * @since 1.1 578: */ 579: public Field[] getFields() 580: { 581: memberAccessCheck(Member.PUBLIC); 582: return internalGetFields(); 583: } 584: 585: /** 586: * Like <code>getFields()</code> but without the security checks. 587: */ 588: private Field[] internalGetFields() 589: { 590: HashSet set = new HashSet(); 591: set.addAll(Arrays.asList(getDeclaredFields(true))); 592: Class[] interfaces = getInterfaces(); 593: for (int i = 0; i < interfaces.length; i++) 594: set.addAll(Arrays.asList(interfaces[i].internalGetFields())); 595: Class superClass = getSuperclass(); 596: if (superClass != null) 597: set.addAll(Arrays.asList(superClass.internalGetFields())); 598: return (Field[])set.toArray(new Field[set.size()]); 599: } 600: 601: /** 602: * Returns the <code>Package</code> in which this class is defined 603: * Returns null when this information is not available from the 604: * classloader of this class or when the classloader of this class 605: * is null. 606: * 607: * @return the package for this class, if it is available 608: * @since 1.2 609: */ 610: public Package getPackage() 611: { 612: ClassLoader cl = getClassLoader(); 613: if (cl != null) 614: return cl.getPackage(getPackagePortion(getName())); 615: return null; 616: } 617: 618: /** 619: * Get the interfaces this class <em>directly</em> implements, in the 620: * order that they were declared. This returns an empty array, not null, 621: * for Object, primitives, void, and classes or interfaces with no direct 622: * superinterface. Array types return Cloneable and Serializable. 623: * 624: * @return the interfaces this class directly implements 625: */ 626: public Class[] getInterfaces() 627: { 628: return VMClass.getInterfaces (this); 629: } 630: 631: private static final class MethodKey 632: { 633: private String name; 634: private Class[] params; 635: private Class returnType; 636: private int hash; 637: 638: MethodKey(Method m) 639: { 640: name = m.getName(); 641: params = m.getParameterTypes(); 642: returnType = m.getReturnType(); 643: hash = name.hashCode() ^ returnType.hashCode(); 644: for(int i = 0; i < params.length; i++) 645: { 646: hash ^= params[i].hashCode(); 647: } 648: } 649: 650: public boolean equals(Object o) 651: { 652: if(o instanceof MethodKey) 653: { 654: MethodKey m = (MethodKey)o; 655: if(m.name.equals(name) && m.params.length == params.length && m.returnType == returnType) 656: { 657: for(int i = 0; i < params.length; i++) 658: { 659: if(m.params[i] != params[i]) 660: { 661: return false; 662: } 663: } 664: return true; 665: } 666: } 667: return false; 668: } 669: 670: public int hashCode() 671: { 672: return hash; 673: } 674: } 675: 676: /** 677: * Get a public method declared or inherited in this class, where name is 678: * its simple name. The implicit methods of Object are not available from 679: * interfaces. Constructors (named "<init>" in the class file) and class 680: * initializers (name "<clinit>") are not available. The Virtual 681: * Machine allows multiple methods with the same signature but differing 682: * return types, and the class can inherit multiple methods of the same 683: * return type; in such a case the most specific return types are favored, 684: * then the final choice is arbitrary. If the method takes no argument, an 685: * array of zero elements and null are equivalent for the types argument. 686: * A security check may be performed, with 687: * <code>checkMemberAccess(this, Member.PUBLIC)</code> as well as 688: * <code>checkPackageAccess</code> both having to succeed. 689: * 690: * @param methodName the name of the method 691: * @param types the type of each parameter 692: * @return the method 693: * @throws NoSuchMethodException if the method does not exist 694: * @throws SecurityException if the security check fails 695: * @see #getMethods() 696: * @since 1.1 697: */ 698: public Method getMethod(String methodName, Class[] types) 699: throws NoSuchMethodException 700: { 701: memberAccessCheck(Member.PUBLIC); 702: Method method = internalGetMethod(methodName, types); 703: if (method == null) 704: throw new NoSuchMethodException(methodName); 705: return method; 706: } 707: 708: /** 709: * Like <code>getMethod(String,Class[])</code> but without the security 710: * checks and returns null instead of throwing NoSuchMethodException. 711: */ 712: private Method internalGetMethod(String methodName, Class[] args) 713: { 714: Method match = matchMethod(getDeclaredMethods(true), methodName, args); 715: if (match != null) 716: return match; 717: Class superClass = getSuperclass(); 718: if (superClass != null) 719: { 720: match = superClass.internalGetMethod(methodName, args); 721: if(match != null) 722: return match; 723: } 724: Class[] interfaces = getInterfaces(); 725: for (int i = 0; i < interfaces.length; i++) 726: { 727: match = interfaces[i].internalGetMethod(methodName, args); 728: if (match != null) 729: return match; 730: } 731: return null; 732: } 733: 734: /** 735: * Find the best matching method in <code>list</code> according to 736: * the definition of ``best matching'' used by <code>getMethod()</code> 737: * 738: * <p> 739: * Returns the method if any, otherwise <code>null</code>. 740: * 741: * @param list List of methods to search 742: * @param name Name of method 743: * @param args Method parameter types 744: * @see #getMethod() 745: */ 746: private static Method matchMethod(Method[] list, String name, Class[] args) 747: { 748: Method match = null; 749: for (int i = 0; i < list.length; i++) 750: { 751: Method method = list[i]; 752: if (!method.getName().equals(name)) 753: continue; 754: if (!matchParameters(args, method.getParameterTypes())) 755: continue; 756: if (match == null 757: || match.getReturnType().isAssignableFrom(method.getReturnType())) 758: match = method; 759: } 760: return match; 761: } 762: 763: /** 764: * Check for an exact match between parameter type lists. 765: * Either list may be <code>null</code> to mean a list of 766: * length zero. 767: */ 768: private static boolean matchParameters(Class[] types1, Class[] types2) 769: { 770: if (types1 == null) 771: return types2 == null || types2.length == 0; 772: if (types2 == null) 773: return types1 == null || types1.length == 0; 774: if (types1.length != types2.length) 775: return false; 776: for (int i = 0; i < types1.length; i++) 777: { 778: if (types1[i] != types2[i]) 779: return false; 780: } 781: return true; 782: } 783: 784: /** 785: * Get all the public methods declared in this class or inherited from 786: * superclasses. This returns an array of length 0 if there are no methods, 787: * including for primitive types. This does not include the implicit 788: * methods of interfaces which mirror methods of Object, nor does it 789: * include constructors or the class initialization methods. The Virtual 790: * Machine allows multiple methods with the same signature but differing 791: * return types; all such methods are in the returned array. A security 792: * check may be performed, with 793: * <code>checkMemberAccess(this, Member.PUBLIC)</code> as well as 794: * <code>checkPackageAccess</code> both having to succeed. 795: * 796: * @return all public methods in this class 797: * @throws SecurityException if the security check fails 798: * @since 1.1 799: */ 800: public Method[] getMethods() 801: { 802: memberAccessCheck(Member.PUBLIC); 803: // NOTE the API docs claim that no methods are returned for arrays, 804: // but Sun's implementation *does* return the public methods of Object 805: // (as would be expected), so we follow their implementation instead 806: // of their documentation. 807: return internalGetMethods(); 808: } 809: 810: /** 811: * Like <code>getMethods()</code> but without the security checks. 812: */ 813: private Method[] internalGetMethods() 814: { 815: HashMap map = new HashMap(); 816: Method[] methods; 817: Class[] interfaces = getInterfaces(); 818: for(int i = 0; i < interfaces.length; i++) 819: { 820: methods = interfaces[i].internalGetMethods(); 821: for(int j = 0; j < methods.length; j++) 822: { 823: map.put(new MethodKey(methods[j]), methods[j]); 824: } 825: } 826: Class superClass = getSuperclass(); 827: if(superClass != null) 828: { 829: methods = superClass.internalGetMethods(); 830: for(int i = 0; i < methods.length; i++) 831: { 832: map.put(new MethodKey(methods[i]), methods[i]); 833: } 834: } 835: methods = getDeclaredMethods(true); 836: for(int i = 0; i < methods.length; i++) 837: { 838: map.put(new MethodKey(methods[i]), methods[i]); 839: } 840: return (Method[])map.values().toArray(new Method[map.size()]); 841: } 842: 843: /** 844: * Get the modifiers of this class. These can be decoded using Modifier, 845: * and is limited to one of public, protected, or private, and any of 846: * final, static, abstract, or interface. An array class has the same 847: * public, protected, or private modifier as its component type, and is 848: * marked final but not an interface. Primitive types and void are marked 849: * public and final, but not an interface. 850: * 851: * @return the modifiers of this class 852: * @see Modifer 853: * @since 1.1 854: */ 855: public int getModifiers() 856: { 857: return VMClass.getModifiers (this, false); 858: } 859: 860: /** 861: * Get the name of this class, separated by dots for package separators. 862: * If the class represents a primitive type, or void, then the 863: * name of the type as it appears in the Java programming language 864: * is returned. For instance, <code>Byte.TYPE.getName()</code> 865: * returns "byte". 866: * 867: * Arrays are specially encoded as shown on this table. 868: * <pre> 869: * array type [<em>element type</em> 870: * (note that the element type is encoded per 871: * this table) 872: * boolean Z 873: * byte B 874: * char C 875: * short S 876: * int I 877: * long J 878: * float F 879: * double D 880: * void V 881: * class or interface, alone: <dotted name> 882: * class or interface, as element type: L<dotted name>; 883: * </pre> 884: * 885: * @return the name of this class 886: */ 887: public String getName() 888: { 889: return VMClass.getName (this); 890: } 891: 892: /** 893: * Get a resource URL using this class's package using the 894: * getClassLoader().getResource() method. If this class was loaded using 895: * the system classloader, ClassLoader.getSystemResource() is used instead. 896: * 897: * <p>If the name you supply is absolute (it starts with a <code>/</code>), 898: * then the leading <code>/</code> is removed and it is passed on to 899: * getResource(). If it is relative, the package name is prepended, and 900: * <code>.</code>'s are replaced with <code>/</code>. 901: * 902: * <p>The URL returned is system- and classloader-dependent, and could 903: * change across implementations. 904: * 905: * @param resourceName the name of the resource, generally a path 906: * @return the URL to the resource 907: * @throws NullPointerException if name is null 908: * @since 1.1 909: */ 910: public URL getResource(String resourceName) 911: { 912: String name = resourcePath(resourceName); 913: ClassLoader loader = getClassLoader(); 914: if (loader == null) 915: return ClassLoader.getSystemResource(name); 916: return loader.getResource(name); 917: } 918: 919: /** 920: * Get a resource using this class's package using the 921: * getClassLoader().getResourceAsStream() method. If this class was loaded 922: * using the system classloader, ClassLoader.getSystemResource() is used 923: * instead. 924: * 925: * <p>If the name you supply is absolute (it starts with a <code>/</code>), 926: * then the leading <code>/</code> is removed and it is passed on to 927: * getResource(). If it is relative, the package name is prepended, and 928: * <code>.</code>'s are replaced with <code>/</code>. 929: * 930: * <p>The URL returned is system- and classloader-dependent, and could 931: * change across implementations. 932: * 933: * @param resourceName the name of the resource, generally a path 934: * @return an InputStream with the contents of the resource in it, or null 935: * @throws NullPointerException if name is null 936: * @since 1.1 937: */ 938: public InputStream getResourceAsStream(String resourceName) 939: { 940: String name = resourcePath(resourceName); 941: ClassLoader loader = getClassLoader(); 942: if (loader == null) 943: return ClassLoader.getSystemResourceAsStream(name); 944: return loader.getResourceAsStream(name); 945: } 946: 947: private String resourcePath(String resourceName) 948: { 949: if (resourceName.length() > 0) 950: { 951: if (resourceName.charAt(0) != '/') 952: { 953: String pkg = getPackagePortion(getName()); 954: if (pkg.length() > 0) 955: resourceName = pkg.replace('.','/') + '/' + resourceName; 956: } 957: else 958: { 959: resourceName = resourceName.substring(1); 960: } 961: } 962: return resourceName; 963: } 964: 965: /** 966: * Get the signers of this class. This returns null if there are no signers, 967: * such as for primitive types or void. 968: * 969: * @return the signers of this class 970: * @since 1.1 971: */ 972: public Object[] getSigners() 973: { 974: return signers == null ? null : (Object[]) signers.clone (); 975: } 976: 977: /** 978: * Set the signers of this class. 979: * 980: * @param signers the signers of this class 981: */ 982: void setSigners(Object[] signers) 983: { 984: this.signers = signers; 985: } 986: 987: /** 988: * Get the direct superclass of this class. If this is an interface, 989: * Object, a primitive type, or void, it will return null. If this is an 990: * array type, it will return Object. 991: * 992: * @return the direct superclass of this class 993: */ 994: public Class getSuperclass() 995: { 996: return VMClass.getSuperclass (this); 997: } 998: 999: /** 1000: * Return whether this class is an array type. 1001: * 1002: * @return whether this class is an array type 1003: * @since 1.1 1004: */ 1005: public boolean isArray() 1006: { 1007: return VMClass.isArray (this); 1008: } 1009: 1010: /** 1011: * Discover whether an instance of the Class parameter would be an 1012: * instance of this Class as well. Think of doing 1013: * <code>isInstance(c.newInstance())</code> or even 1014: * <code>c.newInstance() instanceof (this class)</code>. While this 1015: * checks widening conversions for objects, it must be exact for primitive 1016: * types. 1017: * 1018: * @param c the class to check 1019: * @return whether an instance of c would be an instance of this class 1020: * as well 1021: * @throws NullPointerException if c is null 1022: * @since 1.1 1023: */ 1024: public boolean isAssignableFrom(Class c) 1025: { 1026: return VMClass.isAssignableFrom (this, c); 1027: } 1028: 1029: /** 1030: * Discover whether an Object is an instance of this Class. Think of it 1031: * as almost like <code>o instanceof (this class)</code>. 1032: * 1033: * @param o the Object to check 1034: * @return whether o is an instance of this class 1035: * @since 1.1 1036: */ 1037: public boolean isInstance(Object o) 1038: { 1039: return VMClass.isInstance (this, o); 1040: } 1041: 1042: /** 1043: * Check whether this class is an interface or not. Array types are not 1044: * interfaces. 1045: * 1046: * @return whether this class is an interface or not 1047: */ 1048: public boolean isInterface() 1049: { 1050: return VMClass.isInterface (this); 1051: } 1052: 1053: /** 1054: * Return whether this class is a primitive type. A primitive type class 1055: * is a class representing a kind of "placeholder" for the various 1056: * primitive types, or void. You can access the various primitive type 1057: * classes through java.lang.Boolean.TYPE, java.lang.Integer.TYPE, etc., 1058: * or through boolean.class, int.class, etc. 1059: * 1060: * @return whether this class is a primitive type 1061: * @see Boolean#TYPE 1062: * @see Byte#TYPE 1063: * @see Character#TYPE 1064: * @see Short#TYPE 1065: * @see Integer#TYPE 1066: * @see Long#TYPE 1067: * @see Float#TYPE 1068: * @see Double#TYPE 1069: * @see Void#TYPE 1070: * @since 1.1 1071: */ 1072: public boolean isPrimitive() 1073: { 1074: return VMClass.isPrimitive (this); 1075: } 1076: 1077: /** 1078: * Get a new instance of this class by calling the no-argument constructor. 1079: * The class is initialized if it has not been already. A security check 1080: * may be performed, with <code>checkMemberAccess(this, Member.PUBLIC)</code> 1081: * as well as <code>checkPackageAccess</code> both having to succeed. 1082: * 1083: * @return a new instance of this class 1084: * @throws InstantiationException if there is not a no-arg constructor 1085: * for this class, including interfaces, abstract classes, arrays, 1086: * primitive types, and void; or if an exception occurred during 1087: * the constructor 1088: * @throws IllegalAccessException if you are not allowed to access the 1089: * no-arg constructor because of scoping reasons 1090: * @throws SecurityException if the security check fails 1091: * @throws ExceptionInInitializerError if class initialization caused by 1092: * this call fails with an exception 1093: */ 1094: public Object newInstance() 1095: throws InstantiationException, IllegalAccessException 1096: { 1097: memberAccessCheck(Member.PUBLIC); 1098: Constructor constructor; 1099: synchronized(this) 1100: { 1101: constructor = this.constructor; 1102: } 1103: if (constructor == null) 1104: { 1105: Constructor[] constructors = getDeclaredConstructors(false); 1106: for (int i = 0; i < constructors.length; i++) 1107: { 1108: if (constructors[i].getParameterTypes().length == 0) 1109: { 1110: constructor = constructors[i]; 1111: break; 1112: } 1113: } 1114: if (constructor == null) 1115: throw new InstantiationException(getName()); 1116: if (!Modifier.isPublic(constructor.getModifiers()) 1117: || !Modifier.isPublic(VMClass.getModifiers(this, true))) 1118: { 1119: final Constructor finalConstructor = constructor; 1120: AccessController.doPrivileged(new PrivilegedAction() 1121: { 1122: public Object run() 1123: { 1124: finalConstructor.setAccessible(true); 1125: return null; 1126: } 1127: }); 1128: } 1129: synchronized(this) 1130: { 1131: if (this.constructor == null) 1132: this.constructor = constructor; 1133: } 1134: } 1135: int modifiers = constructor.getModifiers(); 1136: if (!Modifier.isPublic(modifiers) 1137: || !Modifier.isPublic(VMClass.getModifiers(this, true))) 1138: { 1139: Class caller = VMStackWalker.getCallingClass(); 1140: if (caller != null && 1141: caller != this && 1142: (Modifier.isPrivate(modifiers) 1143: || getClassLoader() != caller.getClassLoader() 1144: || !getPackagePortion(getName()) 1145: .equals(getPackagePortion(caller.getName())))) 1146: throw new IllegalAccessException(getName() 1147: + " has an inaccessible constructor"); 1148: } 1149: try 1150: { 1151: return constructor.newInstance(null); 1152: } 1153: catch (InvocationTargetException e) 1154: { 1155: VMClass.throwException(e.getTargetException()); 1156: throw (InternalError) new InternalError 1157: ("VMClass.throwException returned").initCause(e); 1158: } 1159: } 1160: 1161: /** 1162: * Returns the protection domain of this class. If the classloader did not 1163: * record the protection domain when creating this class the unknown 1164: * protection domain is returned which has a <code>null</code> code source 1165: * and all permissions. A security check may be performed, with 1166: * <code>RuntimePermission("getProtectionDomain")</code>. 1167: * 1168: * @return the protection domain 1169: * @throws SecurityException if the security manager exists and the caller 1170: * does not have <code>RuntimePermission("getProtectionDomain")</code>. 1171: * @see RuntimePermission 1172: * @since 1.2 1173: */ 1174: public ProtectionDomain getProtectionDomain() 1175: { 1176: SecurityManager sm = SecurityManager.current; 1177: if (sm != null) 1178: sm.checkPermission(new RuntimePermission("getProtectionDomain")); 1179: 1180: return pd == null ? StaticData.unknownProtectionDomain : pd; 1181: } 1182: 1183: /** 1184: * Return the human-readable form of this Object. For an object, this 1185: * is either "interface " or "class " followed by <code>getName()</code>, 1186: * for primitive types and void it is just <code>getName()</code>. 1187: * 1188: * @return the human-readable form of this Object 1189: */ 1190: public String toString() 1191: { 1192: if (isPrimitive()) 1193: return getName(); 1194: return (isInterface() ? "interface " : "class ") + getName(); 1195: } 1196: 1197: /** 1198: * Returns the desired assertion status of this class, if it were to be 1199: * initialized at this moment. The class assertion status, if set, is 1200: * returned; the backup is the default package status; then if there is 1201: * a class loader, that default is returned; and finally the system default 1202: * is returned. This method seldom needs calling in user code, but exists 1203: * for compilers to implement the assert statement. Note that there is no 1204: * guarantee that the result of this method matches the class's actual 1205: * assertion status. 1206: * 1207: * @return the desired assertion status 1208: * @see ClassLoader#setClassAssertionStatus(String, boolean) 1209: * @see ClassLoader#setPackageAssertionStatus(String, boolean) 1210: * @see ClassLoader#setDefaultAssertionStatus(boolean) 1211: * @since 1.4 1212: */ 1213: public boolean desiredAssertionStatus() 1214: { 1215: ClassLoader c = getClassLoader(); 1216: Object status; 1217: if (c == null) 1218: return VMClassLoader.defaultAssertionStatus(); 1219: if (c.classAssertionStatus != null) 1220: synchronized (c) 1221: { 1222: status = c.classAssertionStatus.get(getName()); 1223: if (status != null) 1224: return status.equals(Boolean.TRUE); 1225: } 1226: else 1227: { 1228: status = ClassLoader.StaticData. 1229: systemClassAssertionStatus.get(getName()); 1230: if (status != null) 1231: return status.equals(Boolean.TRUE); 1232: } 1233: if (c.packageAssertionStatus != null) 1234: synchronized (c) 1235: { 1236: String name = getPackagePortion(getName()); 1237: if ("".equals(name)) 1238: status = c.packageAssertionStatus.get(null); 1239: else 1240: do 1241: { 1242: status = c.packageAssertionStatus.get(name); 1243: name = getPackagePortion(name); 1244: } 1245: while (! "".equals(name) && status == null); 1246: if (status != null) 1247: return status.equals(Boolean.TRUE); 1248: } 1249: else 1250: { 1251: String name = getPackagePortion(getName()); 1252: if ("".equals(name)) 1253: status = ClassLoader.StaticData. 1254: systemPackageAssertionStatus.get(null); 1255: else 1256: do 1257: { 1258: status = ClassLoader.StaticData. 1259: systemPackageAssertionStatus.get(name); 1260: name = getPackagePortion(name); 1261: } 1262: while (! "".equals(name) && status == null); 1263: if (status != null) 1264: return status.equals(Boolean.TRUE); 1265: } 1266: return c.defaultAssertionStatus; 1267: } 1268: 1269: /** 1270: * Like <code>getField(String)</code> but without the security checks and returns null 1271: * instead of throwing NoSuchFieldException. 1272: */ 1273: private Field internalGetField(String name) 1274: { 1275: Field[] fields = getDeclaredFields(true); 1276: for (int i = 0; i < fields.length; i++) 1277: { 1278: Field field = fields[i]; 1279: if (field.getName().equals(name)) 1280: return field; 1281: } 1282: Class[] interfaces = getInterfaces(); 1283: for (int i = 0; i < interfaces.length; i++) 1284: { 1285: Field field = interfaces[i].internalGetField(name); 1286: if(field != null) 1287: return field; 1288: } 1289: Class superClass = getSuperclass(); 1290: if (superClass != null) 1291: return superClass.internalGetField(name); 1292: return null; 1293: } 1294: 1295: /** 1296: * Strip the last portion of the name (after the last dot). 1297: * 1298: * @param name the name to get package of 1299: * @return the package name, or "" if no package 1300: */ 1301: private static String getPackagePortion(String name) 1302: { 1303: int lastInd = name.lastIndexOf('.'); 1304: if (lastInd == -1) 1305: return ""; 1306: return name.substring(0, lastInd); 1307: } 1308: 1309: /** 1310: * Perform security checks common to all of the methods that 1311: * get members of this Class. 1312: */ 1313: private void memberAccessCheck(int which) 1314: { 1315: SecurityManager sm = SecurityManager.current; 1316: if (sm != null) 1317: { 1318: sm.checkMemberAccess(this, which); 1319: Package pkg = getPackage(); 1320: if (pkg != null) 1321: sm.checkPackageAccess(pkg.getName()); 1322: } 1323: } 1324: }
GNU Classpath (0.17) |