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