GNU Classpath (0.20) | |
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. 587: * 588: * @return the package for this class, if it is available 589: * @since 1.2 590: */ 591: public Package getPackage() 592: { 593: ClassLoader cl = getClassLoader(); 594: if (cl != null) 595: return cl.getPackage(getPackagePortion(getName())); 596: else 597: return VMClassLoader.getPackage(getPackagePortion(getName())); 598: } 599: 600: /** 601: * Get the interfaces this class <em>directly</em> implements, in the 602: * order that they were declared. This returns an empty array, not null, 603: * for Object, primitives, void, and classes or interfaces with no direct 604: * superinterface. Array types return Cloneable and Serializable. 605: * 606: * @return the interfaces this class directly implements 607: */ 608: public Class[] getInterfaces() 609: { 610: return VMClass.getInterfaces (this); 611: } 612: 613: private static final class MethodKey 614: { 615: private String name; 616: private Class[] params; 617: private Class returnType; 618: private int hash; 619: 620: MethodKey(Method m) 621: { 622: name = m.getName(); 623: params = m.getParameterTypes(); 624: returnType = m.getReturnType(); 625: hash = name.hashCode() ^ returnType.hashCode(); 626: for(int i = 0; i < params.length; i++) 627: { 628: hash ^= params[i].hashCode(); 629: } 630: } 631: 632: public boolean equals(Object o) 633: { 634: if(o instanceof MethodKey) 635: { 636: MethodKey m = (MethodKey)o; 637: if(m.name.equals(name) && m.params.length == params.length && m.returnType == returnType) 638: { 639: for(int i = 0; i < params.length; i++) 640: { 641: if(m.params[i] != params[i]) 642: { 643: return false; 644: } 645: } 646: return true; 647: } 648: } 649: return false; 650: } 651: 652: public int hashCode() 653: { 654: return hash; 655: } 656: } 657: 658: /** 659: * Get a public method declared or inherited in this class, where name is 660: * its simple name. The implicit methods of Object are not available from 661: * interfaces. Constructors (named "<init>" in the class file) and class 662: * initializers (name "<clinit>") are not available. The Virtual 663: * Machine allows multiple methods with the same signature but differing 664: * return types, and the class can inherit multiple methods of the same 665: * return type; in such a case the most specific return types are favored, 666: * then the final choice is arbitrary. If the method takes no argument, an 667: * array of zero elements and null are equivalent for the types argument. 668: * A security check may be performed, with 669: * <code>checkMemberAccess(this, Member.PUBLIC)</code> as well as 670: * <code>checkPackageAccess</code> both having to succeed. 671: * 672: * @param methodName the name of the method 673: * @param types the type of each parameter 674: * @return the method 675: * @throws NoSuchMethodException if the method does not exist 676: * @throws SecurityException if the security check fails 677: * @see #getMethods() 678: * @since 1.1 679: */ 680: public Method getMethod(String methodName, Class[] types) 681: throws NoSuchMethodException 682: { 683: memberAccessCheck(Member.PUBLIC); 684: Method method = internalGetMethod(methodName, types); 685: if (method == null) 686: throw new NoSuchMethodException(methodName); 687: return method; 688: } 689: 690: /** 691: * Like <code>getMethod(String,Class[])</code> but without the security 692: * checks and returns null instead of throwing NoSuchMethodException. 693: */ 694: private Method internalGetMethod(String methodName, Class[] args) 695: { 696: Method match = matchMethod(getDeclaredMethods(true), methodName, args); 697: if (match != null) 698: return match; 699: Class superClass = getSuperclass(); 700: if (superClass != null) 701: { 702: match = superClass.internalGetMethod(methodName, args); 703: if(match != null) 704: return match; 705: } 706: Class[] interfaces = getInterfaces(); 707: for (int i = 0; i < interfaces.length; i++) 708: { 709: match = interfaces[i].internalGetMethod(methodName, args); 710: if (match != null) 711: return match; 712: } 713: return null; 714: } 715: 716: /** 717: * Find the best matching method in <code>list</code> according to 718: * the definition of ``best matching'' used by <code>getMethod()</code> 719: * 720: * <p> 721: * Returns the method if any, otherwise <code>null</code>. 722: * 723: * @param list List of methods to search 724: * @param name Name of method 725: * @param args Method parameter types 726: * @see #getMethod(String, Class[]) 727: */ 728: private static Method matchMethod(Method[] list, String name, Class[] args) 729: { 730: Method match = null; 731: for (int i = 0; i < list.length; i++) 732: { 733: Method method = list[i]; 734: if (!method.getName().equals(name)) 735: continue; 736: if (!matchParameters(args, method.getParameterTypes())) 737: continue; 738: if (match == null 739: || match.getReturnType().isAssignableFrom(method.getReturnType())) 740: match = method; 741: } 742: return match; 743: } 744: 745: /** 746: * Check for an exact match between parameter type lists. 747: * Either list may be <code>null</code> to mean a list of 748: * length zero. 749: */ 750: private static boolean matchParameters(Class[] types1, Class[] types2) 751: { 752: if (types1 == null) 753: return types2 == null || types2.length == 0; 754: if (types2 == null) 755: return types1 == null || types1.length == 0; 756: if (types1.length != types2.length) 757: return false; 758: for (int i = 0; i < types1.length; i++) 759: { 760: if (types1[i] != types2[i]) 761: return false; 762: } 763: return true; 764: } 765: 766: /** 767: * Get all the public methods declared in this class or inherited from 768: * superclasses. This returns an array of length 0 if there are no methods, 769: * including for primitive types. This does not include the implicit 770: * methods of interfaces which mirror methods of Object, nor does it 771: * include constructors or the class initialization methods. The Virtual 772: * Machine allows multiple methods with the same signature but differing 773: * return types; all such methods are in the returned array. A security 774: * check may be performed, with 775: * <code>checkMemberAccess(this, Member.PUBLIC)</code> as well as 776: * <code>checkPackageAccess</code> both having to succeed. 777: * 778: * @return all public methods in this class 779: * @throws SecurityException if the security check fails 780: * @since 1.1 781: */ 782: public Method[] getMethods() 783: { 784: memberAccessCheck(Member.PUBLIC); 785: // NOTE the API docs claim that no methods are returned for arrays, 786: // but Sun's implementation *does* return the public methods of Object 787: // (as would be expected), so we follow their implementation instead 788: // of their documentation. 789: return internalGetMethods(); 790: } 791: 792: /** 793: * Like <code>getMethods()</code> but without the security checks. 794: */ 795: private Method[] internalGetMethods() 796: { 797: HashMap map = new HashMap(); 798: Method[] methods; 799: Class[] interfaces = getInterfaces(); 800: for(int i = 0; i < interfaces.length; i++) 801: { 802: methods = interfaces[i].internalGetMethods(); 803: for(int j = 0; j < methods.length; j++) 804: { 805: map.put(new MethodKey(methods[j]), methods[j]); 806: } 807: } 808: Class superClass = getSuperclass(); 809: if(superClass != null) 810: { 811: methods = superClass.internalGetMethods(); 812: for(int i = 0; i < methods.length; i++) 813: { 814: map.put(new MethodKey(methods[i]), methods[i]); 815: } 816: } 817: methods = getDeclaredMethods(true); 818: for(int i = 0; i < methods.length; i++) 819: { 820: map.put(new MethodKey(methods[i]), methods[i]); 821: } 822: return (Method[])map.values().toArray(new Method[map.size()]); 823: } 824: 825: /** 826: * Get the modifiers of this class. These can be decoded using Modifier, 827: * and is limited to one of public, protected, or private, and any of 828: * final, static, abstract, or interface. An array class has the same 829: * public, protected, or private modifier as its component type, and is 830: * marked final but not an interface. Primitive types and void are marked 831: * public and final, but not an interface. 832: * 833: * @return the modifiers of this class 834: * @see Modifier 835: * @since 1.1 836: */ 837: public int getModifiers() 838: { 839: int mod = VMClass.getModifiers (this, false); 840: return (mod & (Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE | 841: Modifier.FINAL | Modifier.STATIC | Modifier.ABSTRACT | 842: Modifier.INTERFACE)); 843: } 844: 845: /** 846: * Get the name of this class, separated by dots for package separators. 847: * If the class represents a primitive type, or void, then the 848: * name of the type as it appears in the Java programming language 849: * is returned. For instance, <code>Byte.TYPE.getName()</code> 850: * returns "byte". 851: * 852: * Arrays are specially encoded as shown on this table. 853: * <pre> 854: * array type [<em>element type</em> 855: * (note that the element type is encoded per 856: * this table) 857: * boolean Z 858: * byte B 859: * char C 860: * short S 861: * int I 862: * long J 863: * float F 864: * double D 865: * void V 866: * class or interface, alone: <dotted name> 867: * class or interface, as element type: L<dotted name>; 868: * </pre> 869: * 870: * @return the name of this class 871: */ 872: public String getName() 873: { 874: return VMClass.getName (this); 875: } 876: 877: /** 878: * Get a resource URL using this class's package using the 879: * getClassLoader().getResource() method. If this class was loaded using 880: * the system classloader, ClassLoader.getSystemResource() is used instead. 881: * 882: * <p>If the name you supply is absolute (it starts with a <code>/</code>), 883: * then the leading <code>/</code> is removed and it is passed on to 884: * getResource(). If it is relative, the package name is prepended, and 885: * <code>.</code>'s are replaced with <code>/</code>. 886: * 887: * <p>The URL returned is system- and classloader-dependent, and could 888: * change across implementations. 889: * 890: * @param resourceName the name of the resource, generally a path 891: * @return the URL to the resource 892: * @throws NullPointerException if name is null 893: * @since 1.1 894: */ 895: public URL getResource(String resourceName) 896: { 897: String name = resourcePath(resourceName); 898: ClassLoader loader = getClassLoader(); 899: if (loader == null) 900: return ClassLoader.getSystemResource(name); 901: return loader.getResource(name); 902: } 903: 904: /** 905: * Get a resource using this class's package using the 906: * getClassLoader().getResourceAsStream() method. If this class was loaded 907: * using the system classloader, ClassLoader.getSystemResource() is used 908: * instead. 909: * 910: * <p>If the name you supply is absolute (it starts with a <code>/</code>), 911: * then the leading <code>/</code> is removed and it is passed on to 912: * getResource(). If it is relative, the package name is prepended, and 913: * <code>.</code>'s are replaced with <code>/</code>. 914: * 915: * <p>The URL returned is system- and classloader-dependent, and could 916: * change across implementations. 917: * 918: * @param resourceName the name of the resource, generally a path 919: * @return an InputStream with the contents of the resource in it, or null 920: * @throws NullPointerException if name is null 921: * @since 1.1 922: */ 923: public InputStream getResourceAsStream(String resourceName) 924: { 925: String name = resourcePath(resourceName); 926: ClassLoader loader = getClassLoader(); 927: if (loader == null) 928: return ClassLoader.getSystemResourceAsStream(name); 929: return loader.getResourceAsStream(name); 930: } 931: 932: private String resourcePath(String resourceName) 933: { 934: if (resourceName.length() > 0) 935: { 936: if (resourceName.charAt(0) != '/') 937: { 938: String pkg = getPackagePortion(getName()); 939: if (pkg.length() > 0) 940: resourceName = pkg.replace('.','/') + '/' + resourceName; 941: } 942: else 943: { 944: resourceName = resourceName.substring(1); 945: } 946: } 947: return resourceName; 948: } 949: 950: /** 951: * Get the signers of this class. This returns null if there are no signers, 952: * such as for primitive types or void. 953: * 954: * @return the signers of this class 955: * @since 1.1 956: */ 957: public Object[] getSigners() 958: { 959: return signers == null ? null : (Object[]) signers.clone (); 960: } 961: 962: /** 963: * Set the signers of this class. 964: * 965: * @param signers the signers of this class 966: */ 967: void setSigners(Object[] signers) 968: { 969: this.signers = signers; 970: } 971: 972: /** 973: * Get the direct superclass of this class. If this is an interface, 974: * Object, a primitive type, or void, it will return null. If this is an 975: * array type, it will return Object. 976: * 977: * @return the direct superclass of this class 978: */ 979: public Class getSuperclass() 980: { 981: return VMClass.getSuperclass (this); 982: } 983: 984: /** 985: * Return whether this class is an array type. 986: * 987: * @return whether this class is an array type 988: * @since 1.1 989: */ 990: public boolean isArray() 991: { 992: return VMClass.isArray (this); 993: } 994: 995: /** 996: * Discover whether an instance of the Class parameter would be an 997: * instance of this Class as well. Think of doing 998: * <code>isInstance(c.newInstance())</code> or even 999: * <code>c.newInstance() instanceof (this class)</code>. While this 1000: * checks widening conversions for objects, it must be exact for primitive 1001: * types. 1002: * 1003: * @param c the class to check 1004: * @return whether an instance of c would be an instance of this class 1005: * as well 1006: * @throws NullPointerException if c is null 1007: * @since 1.1 1008: */ 1009: public boolean isAssignableFrom(Class c) 1010: { 1011: return VMClass.isAssignableFrom (this, c); 1012: } 1013: 1014: /** 1015: * Discover whether an Object is an instance of this Class. Think of it 1016: * as almost like <code>o instanceof (this class)</code>. 1017: * 1018: * @param o the Object to check 1019: * @return whether o is an instance of this class 1020: * @since 1.1 1021: */ 1022: public boolean isInstance(Object o) 1023: { 1024: return VMClass.isInstance (this, o); 1025: } 1026: 1027: /** 1028: * Check whether this class is an interface or not. Array types are not 1029: * interfaces. 1030: * 1031: * @return whether this class is an interface or not 1032: */ 1033: public boolean isInterface() 1034: { 1035: return VMClass.isInterface (this); 1036: } 1037: 1038: /** 1039: * Return whether this class is a primitive type. A primitive type class 1040: * is a class representing a kind of "placeholder" for the various 1041: * primitive types, or void. You can access the various primitive type 1042: * classes through java.lang.Boolean.TYPE, java.lang.Integer.TYPE, etc., 1043: * or through boolean.class, int.class, etc. 1044: * 1045: * @return whether this class is a primitive type 1046: * @see Boolean#TYPE 1047: * @see Byte#TYPE 1048: * @see Character#TYPE 1049: * @see Short#TYPE 1050: * @see Integer#TYPE 1051: * @see Long#TYPE 1052: * @see Float#TYPE 1053: * @see Double#TYPE 1054: * @see Void#TYPE 1055: * @since 1.1 1056: */ 1057: public boolean isPrimitive() 1058: { 1059: return VMClass.isPrimitive (this); 1060: } 1061: 1062: /** 1063: * Get a new instance of this class by calling the no-argument constructor. 1064: * The class is initialized if it has not been already. A security check 1065: * may be performed, with <code>checkMemberAccess(this, Member.PUBLIC)</code> 1066: * as well as <code>checkPackageAccess</code> both having to succeed. 1067: * 1068: * @return a new instance of this class 1069: * @throws InstantiationException if there is not a no-arg constructor 1070: * for this class, including interfaces, abstract classes, arrays, 1071: * primitive types, and void; or if an exception occurred during 1072: * the constructor 1073: * @throws IllegalAccessException if you are not allowed to access the 1074: * no-arg constructor because of scoping reasons 1075: * @throws SecurityException if the security check fails 1076: * @throws ExceptionInInitializerError if class initialization caused by 1077: * this call fails with an exception 1078: */ 1079: public Object newInstance() 1080: throws InstantiationException, IllegalAccessException 1081: { 1082: memberAccessCheck(Member.PUBLIC); 1083: Constructor constructor; 1084: synchronized(this) 1085: { 1086: constructor = this.constructor; 1087: } 1088: if (constructor == null) 1089: { 1090: Constructor[] constructors = getDeclaredConstructors(false); 1091: for (int i = 0; i < constructors.length; i++) 1092: { 1093: if (constructors[i].getParameterTypes().length == 0) 1094: { 1095: constructor = constructors[i]; 1096: break; 1097: } 1098: } 1099: if (constructor == null) 1100: throw new InstantiationException(getName()); 1101: if (!Modifier.isPublic(constructor.getModifiers()) 1102: || !Modifier.isPublic(VMClass.getModifiers(this, true))) 1103: { 1104: final Constructor finalConstructor = constructor; 1105: AccessController.doPrivileged(new PrivilegedAction() 1106: { 1107: public Object run() 1108: { 1109: finalConstructor.setAccessible(true); 1110: return null; 1111: } 1112: }); 1113: } 1114: synchronized(this) 1115: { 1116: if (this.constructor == null) 1117: this.constructor = constructor; 1118: } 1119: } 1120: int modifiers = constructor.getModifiers(); 1121: if (!Modifier.isPublic(modifiers) 1122: || !Modifier.isPublic(VMClass.getModifiers(this, true))) 1123: { 1124: Class caller = VMStackWalker.getCallingClass(); 1125: if (caller != null && 1126: caller != this && 1127: (Modifier.isPrivate(modifiers) 1128: || getClassLoader() != caller.getClassLoader() 1129: || !getPackagePortion(getName()) 1130: .equals(getPackagePortion(caller.getName())))) 1131: throw new IllegalAccessException(getName() 1132: + " has an inaccessible constructor"); 1133: } 1134: try 1135: { 1136: return constructor.newInstance(null); 1137: } 1138: catch (InvocationTargetException e) 1139: { 1140: VMClass.throwException(e.getTargetException()); 1141: throw (InternalError) new InternalError 1142: ("VMClass.throwException returned").initCause(e); 1143: } 1144: } 1145: 1146: /** 1147: * Returns the protection domain of this class. If the classloader did not 1148: * record the protection domain when creating this class the unknown 1149: * protection domain is returned which has a <code>null</code> code source 1150: * and all permissions. A security check may be performed, with 1151: * <code>RuntimePermission("getProtectionDomain")</code>. 1152: * 1153: * @return the protection domain 1154: * @throws SecurityException if the security manager exists and the caller 1155: * does not have <code>RuntimePermission("getProtectionDomain")</code>. 1156: * @see RuntimePermission 1157: * @since 1.2 1158: */ 1159: public ProtectionDomain getProtectionDomain() 1160: { 1161: SecurityManager sm = SecurityManager.current; 1162: if (sm != null) 1163: sm.checkPermission(new RuntimePermission("getProtectionDomain")); 1164: 1165: return pd == null ? StaticData.unknownProtectionDomain : pd; 1166: } 1167: 1168: /** 1169: * Return the human-readable form of this Object. For an object, this 1170: * is either "interface " or "class " followed by <code>getName()</code>, 1171: * for primitive types and void it is just <code>getName()</code>. 1172: * 1173: * @return the human-readable form of this Object 1174: */ 1175: public String toString() 1176: { 1177: if (isPrimitive()) 1178: return getName(); 1179: return (isInterface() ? "interface " : "class ") + getName(); 1180: } 1181: 1182: /** 1183: * Returns the desired assertion status of this class, if it were to be 1184: * initialized at this moment. The class assertion status, if set, is 1185: * returned; the backup is the default package status; then if there is 1186: * a class loader, that default is returned; and finally the system default 1187: * is returned. This method seldom needs calling in user code, but exists 1188: * for compilers to implement the assert statement. Note that there is no 1189: * guarantee that the result of this method matches the class's actual 1190: * assertion status. 1191: * 1192: * @return the desired assertion status 1193: * @see ClassLoader#setClassAssertionStatus(String, boolean) 1194: * @see ClassLoader#setPackageAssertionStatus(String, boolean) 1195: * @see ClassLoader#setDefaultAssertionStatus(boolean) 1196: * @since 1.4 1197: */ 1198: public boolean desiredAssertionStatus() 1199: { 1200: ClassLoader c = getClassLoader(); 1201: Object status; 1202: if (c == null) 1203: return VMClassLoader.defaultAssertionStatus(); 1204: if (c.classAssertionStatus != null) 1205: synchronized (c) 1206: { 1207: status = c.classAssertionStatus.get(getName()); 1208: if (status != null) 1209: return status.equals(Boolean.TRUE); 1210: } 1211: else 1212: { 1213: status = ClassLoader.StaticData. 1214: systemClassAssertionStatus.get(getName()); 1215: if (status != null) 1216: return status.equals(Boolean.TRUE); 1217: } 1218: if (c.packageAssertionStatus != null) 1219: synchronized (c) 1220: { 1221: String name = getPackagePortion(getName()); 1222: if ("".equals(name)) 1223: status = c.packageAssertionStatus.get(null); 1224: else 1225: do 1226: { 1227: status = c.packageAssertionStatus.get(name); 1228: name = getPackagePortion(name); 1229: } 1230: while (! "".equals(name) && status == null); 1231: if (status != null) 1232: return status.equals(Boolean.TRUE); 1233: } 1234: else 1235: { 1236: String name = getPackagePortion(getName()); 1237: if ("".equals(name)) 1238: status = ClassLoader.StaticData. 1239: systemPackageAssertionStatus.get(null); 1240: else 1241: do 1242: { 1243: status = ClassLoader.StaticData. 1244: systemPackageAssertionStatus.get(name); 1245: name = getPackagePortion(name); 1246: } 1247: while (! "".equals(name) && status == null); 1248: if (status != null) 1249: return status.equals(Boolean.TRUE); 1250: } 1251: return c.defaultAssertionStatus; 1252: } 1253: 1254: /** 1255: * Like <code>getField(String)</code> but without the security checks and returns null 1256: * instead of throwing NoSuchFieldException. 1257: */ 1258: private Field internalGetField(String name) 1259: { 1260: Field[] fields = getDeclaredFields(true); 1261: for (int i = 0; i < fields.length; i++) 1262: { 1263: Field field = fields[i]; 1264: if (field.getName().equals(name)) 1265: return field; 1266: } 1267: Class[] interfaces = getInterfaces(); 1268: for (int i = 0; i < interfaces.length; i++) 1269: { 1270: Field field = interfaces[i].internalGetField(name); 1271: if(field != null) 1272: return field; 1273: } 1274: Class superClass = getSuperclass(); 1275: if (superClass != null) 1276: return superClass.internalGetField(name); 1277: return null; 1278: } 1279: 1280: /** 1281: * Strip the last portion of the name (after the last dot). 1282: * 1283: * @param name the name to get package of 1284: * @return the package name, or "" if no package 1285: */ 1286: private static String getPackagePortion(String name) 1287: { 1288: int lastInd = name.lastIndexOf('.'); 1289: if (lastInd == -1) 1290: return ""; 1291: return name.substring(0, lastInd); 1292: } 1293: 1294: /** 1295: * Perform security checks common to all of the methods that 1296: * get members of this Class. 1297: */ 1298: private void memberAccessCheck(int which) 1299: { 1300: SecurityManager sm = SecurityManager.current; 1301: if (sm != null) 1302: { 1303: sm.checkMemberAccess(this, which); 1304: Package pkg = getPackage(); 1305: if (pkg != null) 1306: sm.checkPackageAccess(pkg.getName()); 1307: } 1308: } 1309: }
GNU Classpath (0.20) |