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