0001: /*
0002: * Copyright 1994-2006 Sun Microsystems, Inc. All Rights Reserved.
0003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004: *
0005: * This code is free software; you can redistribute it and/or modify it
0006: * under the terms of the GNU General Public License version 2 only, as
0007: * published by the Free Software Foundation. Sun designates this
0008: * particular file as subject to the "Classpath" exception as provided
0009: * by Sun in the LICENSE file that accompanied this code.
0010: *
0011: * This code is distributed in the hope that it will be useful, but WITHOUT
0012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0014: * version 2 for more details (a copy is included in the LICENSE file that
0015: * accompanied this code).
0016: *
0017: * You should have received a copy of the GNU General Public License version
0018: * 2 along with this work; if not, write to the Free Software Foundation,
0019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020: *
0021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022: * CA 95054 USA or visit www.sun.com if you need additional information or
0023: * have any questions.
0024: */
0025:
0026: package java.lang;
0027:
0028: import java.lang.reflect.Array;
0029: import java.lang.reflect.GenericArrayType;
0030: import java.lang.reflect.Member;
0031: import java.lang.reflect.Field;
0032: import java.lang.reflect.Method;
0033: import java.lang.reflect.Constructor;
0034: import java.lang.reflect.GenericDeclaration;
0035: import java.lang.reflect.Modifier;
0036: import java.lang.reflect.Type;
0037: import java.lang.reflect.TypeVariable;
0038: import java.lang.reflect.InvocationTargetException;
0039: import java.lang.ref.SoftReference;
0040: import java.io.InputStream;
0041: import java.io.ObjectStreamField;
0042: import java.security.AccessController;
0043: import java.security.PrivilegedAction;
0044: import java.util.ArrayList;
0045: import java.util.Arrays;
0046: import java.util.Collection;
0047: import java.util.HashSet;
0048: import java.util.Iterator;
0049: import java.util.List;
0050: import java.util.LinkedList;
0051: import java.util.LinkedHashSet;
0052: import java.util.Set;
0053: import java.util.Map;
0054: import java.util.HashMap;
0055: import sun.misc.Unsafe;
0056: import sun.reflect.ConstantPool;
0057: import sun.reflect.Reflection;
0058: import sun.reflect.ReflectionFactory;
0059: import sun.reflect.SignatureIterator;
0060: import sun.reflect.generics.factory.CoreReflectionFactory;
0061: import sun.reflect.generics.factory.GenericsFactory;
0062: import sun.reflect.generics.repository.ClassRepository;
0063: import sun.reflect.generics.repository.MethodRepository;
0064: import sun.reflect.generics.repository.ConstructorRepository;
0065: import sun.reflect.generics.scope.ClassScope;
0066: import sun.security.util.SecurityConstants;
0067: import java.lang.annotation.Annotation;
0068: import sun.reflect.annotation.*;
0069:
0070: /**
0071: * Instances of the class {@code Class} represent classes and
0072: * interfaces in a running Java application. An enum is a kind of
0073: * class and an annotation is a kind of interface. Every array also
0074: * belongs to a class that is reflected as a {@code Class} object
0075: * that is shared by all arrays with the same element type and number
0076: * of dimensions. The primitive Java types ({@code boolean},
0077: * {@code byte}, {@code char}, {@code short},
0078: * {@code int}, {@code long}, {@code float}, and
0079: * {@code double}), and the keyword {@code void} are also
0080: * represented as {@code Class} objects.
0081: *
0082: * <p> {@code Class} has no public constructor. Instead {@code Class}
0083: * objects are constructed automatically by the Java Virtual Machine as classes
0084: * are loaded and by calls to the {@code defineClass} method in the class
0085: * loader.
0086: *
0087: * <p> The following example uses a {@code Class} object to print the
0088: * class name of an object:
0089: *
0090: * <p> <blockquote><pre>
0091: * void printClassName(Object obj) {
0092: * System.out.println("The class of " + obj +
0093: * " is " + obj.getClass().getName());
0094: * }
0095: * </pre></blockquote>
0096: *
0097: * <p> It is also possible to get the {@code Class} object for a named
0098: * type (or for void) using a class literal
0099: * (JLS Section <A HREF="http://java.sun.com/docs/books/jls/second_edition/html/expressions.doc.html#251530">15.8.2</A>).
0100: * For example:
0101: *
0102: * <p> <blockquote>
0103: * {@code System.out.println("The name of class Foo is: "+Foo.class.getName());}
0104: * </blockquote>
0105: *
0106: * @param <T> the type of the class modeled by this {@code Class}
0107: * object. For example, the type of {@code String.class} is {@code
0108: * Class<String>}. Use {@code Class<?>} if the class being modeled is
0109: * unknown.
0110: *
0111: * @author unascribed
0112: * @version 1.211, 07/27/07
0113: * @see java.lang.ClassLoader#defineClass(byte[], int, int)
0114: * @since JDK1.0
0115: */
0116: public final class Class<T> implements java.io.Serializable,
0117: java.lang.reflect.GenericDeclaration, java.lang.reflect.Type,
0118: java.lang.reflect.AnnotatedElement {
0119: private static final int ANNOTATION = 0x00002000;
0120: private static final int ENUM = 0x00004000;
0121: private static final int SYNTHETIC = 0x00001000;
0122:
0123: private static native void registerNatives();
0124:
0125: static {
0126: registerNatives();
0127: }
0128:
0129: /*
0130: * Constructor. Only the Java Virtual Machine creates Class
0131: * objects.
0132: */
0133: private Class() {
0134: }
0135:
0136: /**
0137: * Converts the object to a string. The string representation is the
0138: * string "class" or "interface", followed by a space, and then by the
0139: * fully qualified name of the class in the format returned by
0140: * {@code getName}. If this {@code Class} object represents a
0141: * primitive type, this method returns the name of the primitive type. If
0142: * this {@code Class} object represents void this method returns
0143: * "void".
0144: *
0145: * @return a string representation of this class object.
0146: */
0147: public String toString() {
0148: return (isInterface() ? "interface " : (isPrimitive() ? ""
0149: : "class "))
0150: + getName();
0151: }
0152:
0153: /**
0154: * Returns the {@code Class} object associated with the class or
0155: * interface with the given string name. Invoking this method is
0156: * equivalent to:
0157: *
0158: * <blockquote>
0159: * {@code Class.forName(className, true, currentLoader)}
0160: * </blockquote>
0161: *
0162: * where {@code currentLoader} denotes the defining class loader of
0163: * the current class.
0164: *
0165: * <p> For example, the following code fragment returns the
0166: * runtime {@code Class} descriptor for the class named
0167: * {@code java.lang.Thread}:
0168: *
0169: * <blockquote>
0170: * {@code Class t = Class.forName("java.lang.Thread")}
0171: * </blockquote>
0172: * <p>
0173: * A call to {@code forName("X")} causes the class named
0174: * {@code X} to be initialized.
0175: *
0176: * @param className the fully qualified name of the desired class.
0177: * @return the {@code Class} object for the class with the
0178: * specified name.
0179: * @exception LinkageError if the linkage fails
0180: * @exception ExceptionInInitializerError if the initialization provoked
0181: * by this method fails
0182: * @exception ClassNotFoundException if the class cannot be located
0183: */
0184: public static Class<?> forName(String className)
0185: throws ClassNotFoundException {
0186: return forName0(className, true, ClassLoader
0187: .getCallerClassLoader());
0188: }
0189:
0190: /**
0191: * Returns the {@code Class} object associated with the class or
0192: * interface with the given string name, using the given class loader.
0193: * Given the fully qualified name for a class or interface (in the same
0194: * format returned by {@code getName}) this method attempts to
0195: * locate, load, and link the class or interface. The specified class
0196: * loader is used to load the class or interface. If the parameter
0197: * {@code loader} is null, the class is loaded through the bootstrap
0198: * class loader. The class is initialized only if the
0199: * {@code initialize} parameter is {@code true} and if it has
0200: * not been initialized earlier.
0201: *
0202: * <p> If {@code name} denotes a primitive type or void, an attempt
0203: * will be made to locate a user-defined class in the unnamed package whose
0204: * name is {@code name}. Therefore, this method cannot be used to
0205: * obtain any of the {@code Class} objects representing primitive
0206: * types or void.
0207: *
0208: * <p> If {@code name} denotes an array class, the component type of
0209: * the array class is loaded but not initialized.
0210: *
0211: * <p> For example, in an instance method the expression:
0212: *
0213: * <blockquote>
0214: * {@code Class.forName("Foo")}
0215: * </blockquote>
0216: *
0217: * is equivalent to:
0218: *
0219: * <blockquote>
0220: * {@code Class.forName("Foo", true, this.getClass().getClassLoader())}
0221: * </blockquote>
0222: *
0223: * Note that this method throws errors related to loading, linking or
0224: * initializing as specified in Sections 12.2, 12.3 and 12.4 of <em>The
0225: * Java Language Specification</em>.
0226: * Note that this method does not check whether the requested class
0227: * is accessible to its caller.
0228: *
0229: * <p> If the {@code loader} is {@code null}, and a security
0230: * manager is present, and the caller's class loader is not null, then this
0231: * method calls the security manager's {@code checkPermission} method
0232: * with a {@code RuntimePermission("getClassLoader")} permission to
0233: * ensure it's ok to access the bootstrap class loader.
0234: *
0235: * @param name fully qualified name of the desired class
0236: * @param initialize whether the class must be initialized
0237: * @param loader class loader from which the class must be loaded
0238: * @return class object representing the desired class
0239: *
0240: * @exception LinkageError if the linkage fails
0241: * @exception ExceptionInInitializerError if the initialization provoked
0242: * by this method fails
0243: * @exception ClassNotFoundException if the class cannot be located by
0244: * the specified class loader
0245: *
0246: * @see java.lang.Class#forName(String)
0247: * @see java.lang.ClassLoader
0248: * @since 1.2
0249: */
0250: public static Class<?> forName(String name, boolean initialize,
0251: ClassLoader loader) throws ClassNotFoundException {
0252: if (loader == null) {
0253: SecurityManager sm = System.getSecurityManager();
0254: if (sm != null) {
0255: ClassLoader ccl = ClassLoader.getCallerClassLoader();
0256: if (ccl != null) {
0257: sm
0258: .checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
0259: }
0260: }
0261: }
0262: return forName0(name, initialize, loader);
0263: }
0264:
0265: /** Called after security checks have been made. */
0266: private static native Class forName0(String name,
0267: boolean initialize, ClassLoader loader)
0268: throws ClassNotFoundException;
0269:
0270: /**
0271: * Creates a new instance of the class represented by this {@code Class}
0272: * object. The class is instantiated as if by a {@code new}
0273: * expression with an empty argument list. The class is initialized if it
0274: * has not already been initialized.
0275: *
0276: * <p>Note that this method propagates any exception thrown by the
0277: * nullary constructor, including a checked exception. Use of
0278: * this method effectively bypasses the compile-time exception
0279: * checking that would otherwise be performed by the compiler.
0280: * The {@link
0281: * java.lang.reflect.Constructor#newInstance(java.lang.Object...)
0282: * Constructor.newInstance} method avoids this problem by wrapping
0283: * any exception thrown by the constructor in a (checked) {@link
0284: * java.lang.reflect.InvocationTargetException}.
0285: *
0286: * @return a newly allocated instance of the class represented by this
0287: * object.
0288: * @exception IllegalAccessException if the class or its nullary
0289: * constructor is not accessible.
0290: * @exception InstantiationException
0291: * if this {@code Class} represents an abstract class,
0292: * an interface, an array class, a primitive type, or void;
0293: * or if the class has no nullary constructor;
0294: * or if the instantiation fails for some other reason.
0295: * @exception ExceptionInInitializerError if the initialization
0296: * provoked by this method fails.
0297: * @exception SecurityException
0298: * If a security manager, <i>s</i>, is present and any of the
0299: * following conditions is met:
0300: *
0301: * <ul>
0302: *
0303: * <li> invocation of
0304: * {@link SecurityManager#checkMemberAccess
0305: * s.checkMemberAccess(this, Member.PUBLIC)} denies
0306: * creation of new instances of this class
0307: *
0308: * <li> the caller's class loader is not the same as or an
0309: * ancestor of the class loader for the current class and
0310: * invocation of {@link SecurityManager#checkPackageAccess
0311: * s.checkPackageAccess()} denies access to the package
0312: * of this class
0313: *
0314: * </ul>
0315: *
0316: */
0317: public T newInstance() throws InstantiationException,
0318: IllegalAccessException {
0319: if (System.getSecurityManager() != null) {
0320: checkMemberAccess(Member.PUBLIC, ClassLoader
0321: .getCallerClassLoader());
0322: }
0323: return newInstance0();
0324: }
0325:
0326: private T newInstance0() throws InstantiationException,
0327: IllegalAccessException {
0328: // NOTE: the following code may not be strictly correct under
0329: // the current Java memory model.
0330:
0331: // Constructor lookup
0332: if (cachedConstructor == null) {
0333: if (this == Class.class) {
0334: throw new IllegalAccessException(
0335: "Can not call newInstance() on the Class for java.lang.Class");
0336: }
0337: try {
0338: Class[] empty = {};
0339: final Constructor<T> c = getConstructor0(empty,
0340: Member.DECLARED);
0341: // Disable accessibility checks on the constructor
0342: // since we have to do the security check here anyway
0343: // (the stack depth is wrong for the Constructor's
0344: // security check to work)
0345: java.security.AccessController
0346: .doPrivileged(new java.security.PrivilegedAction() {
0347: public Object run() {
0348: c.setAccessible(true);
0349: return null;
0350: }
0351: });
0352: cachedConstructor = c;
0353: } catch (NoSuchMethodException e) {
0354: throw new InstantiationException(getName());
0355: }
0356: }
0357: Constructor<T> tmpConstructor = cachedConstructor;
0358: // Security check (same as in java.lang.reflect.Constructor)
0359: int modifiers = tmpConstructor.getModifiers();
0360: if (!Reflection.quickCheckMemberAccess(this , modifiers)) {
0361: Class caller = Reflection.getCallerClass(3);
0362: if (newInstanceCallerCache != caller) {
0363: Reflection.ensureMemberAccess(caller, this , null,
0364: modifiers);
0365: newInstanceCallerCache = caller;
0366: }
0367: }
0368: // Run constructor
0369: try {
0370: return tmpConstructor.newInstance((Object[]) null);
0371: } catch (InvocationTargetException e) {
0372: Unsafe.getUnsafe().throwException(e.getTargetException());
0373: // Not reached
0374: return null;
0375: }
0376: }
0377:
0378: private volatile transient Constructor<T> cachedConstructor;
0379: private volatile transient Class newInstanceCallerCache;
0380:
0381: /**
0382: * Determines if the specified {@code Object} is assignment-compatible
0383: * with the object represented by this {@code Class}. This method is
0384: * the dynamic equivalent of the Java language {@code instanceof}
0385: * operator. The method returns {@code true} if the specified
0386: * {@code Object} argument is non-null and can be cast to the
0387: * reference type represented by this {@code Class} object without
0388: * raising a {@code ClassCastException.} It returns {@code false}
0389: * otherwise.
0390: *
0391: * <p> Specifically, if this {@code Class} object represents a
0392: * declared class, this method returns {@code true} if the specified
0393: * {@code Object} argument is an instance of the represented class (or
0394: * of any of its subclasses); it returns {@code false} otherwise. If
0395: * this {@code Class} object represents an array class, this method
0396: * returns {@code true} if the specified {@code Object} argument
0397: * can be converted to an object of the array class by an identity
0398: * conversion or by a widening reference conversion; it returns
0399: * {@code false} otherwise. If this {@code Class} object
0400: * represents an interface, this method returns {@code true} if the
0401: * class or any superclass of the specified {@code Object} argument
0402: * implements this interface; it returns {@code false} otherwise. If
0403: * this {@code Class} object represents a primitive type, this method
0404: * returns {@code false}.
0405: *
0406: * @param obj the object to check
0407: * @return true if {@code obj} is an instance of this class
0408: *
0409: * @since JDK1.1
0410: */
0411: public native boolean isInstance(Object obj);
0412:
0413: /**
0414: * Determines if the class or interface represented by this
0415: * {@code Class} object is either the same as, or is a superclass or
0416: * superinterface of, the class or interface represented by the specified
0417: * {@code Class} parameter. It returns {@code true} if so;
0418: * otherwise it returns {@code false}. If this {@code Class}
0419: * object represents a primitive type, this method returns
0420: * {@code true} if the specified {@code Class} parameter is
0421: * exactly this {@code Class} object; otherwise it returns
0422: * {@code false}.
0423: *
0424: * <p> Specifically, this method tests whether the type represented by the
0425: * specified {@code Class} parameter can be converted to the type
0426: * represented by this {@code Class} object via an identity conversion
0427: * or via a widening reference conversion. See <em>The Java Language
0428: * Specification</em>, sections 5.1.1 and 5.1.4 , for details.
0429: *
0430: * @param cls the {@code Class} object to be checked
0431: * @return the {@code boolean} value indicating whether objects of the
0432: * type {@code cls} can be assigned to objects of this class
0433: * @exception NullPointerException if the specified Class parameter is
0434: * null.
0435: * @since JDK1.1
0436: */
0437: public native boolean isAssignableFrom(Class<?> cls);
0438:
0439: /**
0440: * Determines if the specified {@code Class} object represents an
0441: * interface type.
0442: *
0443: * @return {@code true} if this object represents an interface;
0444: * {@code false} otherwise.
0445: */
0446: public native boolean isInterface();
0447:
0448: /**
0449: * Determines if this {@code Class} object represents an array class.
0450: *
0451: * @return {@code true} if this object represents an array class;
0452: * {@code false} otherwise.
0453: * @since JDK1.1
0454: */
0455: public native boolean isArray();
0456:
0457: /**
0458: * Determines if the specified {@code Class} object represents a
0459: * primitive type.
0460: *
0461: * <p> There are nine predefined {@code Class} objects to represent
0462: * the eight primitive types and void. These are created by the Java
0463: * Virtual Machine, and have the same names as the primitive types that
0464: * they represent, namely {@code boolean}, {@code byte},
0465: * {@code char}, {@code short}, {@code int},
0466: * {@code long}, {@code float}, and {@code double}.
0467: *
0468: * <p> These objects may only be accessed via the following public static
0469: * final variables, and are the only {@code Class} objects for which
0470: * this method returns {@code true}.
0471: *
0472: * @return true if and only if this class represents a primitive type
0473: *
0474: * @see java.lang.Boolean#TYPE
0475: * @see java.lang.Character#TYPE
0476: * @see java.lang.Byte#TYPE
0477: * @see java.lang.Short#TYPE
0478: * @see java.lang.Integer#TYPE
0479: * @see java.lang.Long#TYPE
0480: * @see java.lang.Float#TYPE
0481: * @see java.lang.Double#TYPE
0482: * @see java.lang.Void#TYPE
0483: * @since JDK1.1
0484: */
0485: public native boolean isPrimitive();
0486:
0487: /**
0488: * Returns true if this {@code Class} object represents an annotation
0489: * type. Note that if this method returns true, {@link #isInterface()}
0490: * would also return true, as all annotation types are also interfaces.
0491: *
0492: * @return {@code true} if this class object represents an annotation
0493: * type; {@code false} otherwise
0494: * @since 1.5
0495: */
0496: public boolean isAnnotation() {
0497: return (getModifiers() & ANNOTATION) != 0;
0498: }
0499:
0500: /**
0501: * Returns {@code true} if this class is a synthetic class;
0502: * returns {@code false} otherwise.
0503: * @return {@code true} if and only if this class is a synthetic class as
0504: * defined by the Java Language Specification.
0505: * @since 1.5
0506: */
0507: public boolean isSynthetic() {
0508: return (getModifiers() & SYNTHETIC) != 0;
0509: }
0510:
0511: /**
0512: * Returns the name of the entity (class, interface, array class,
0513: * primitive type, or void) represented by this {@code Class} object,
0514: * as a {@code String}.
0515: *
0516: * <p> If this class object represents a reference type that is not an
0517: * array type then the binary name of the class is returned, as specified
0518: * by the Java Language Specification, Second Edition.
0519: *
0520: * <p> If this class object represents a primitive type or void, then the
0521: * name returned is a {@code String} equal to the Java language
0522: * keyword corresponding to the primitive type or void.
0523: *
0524: * <p> If this class object represents a class of arrays, then the internal
0525: * form of the name consists of the name of the element type preceded by
0526: * one or more '{@code [}' characters representing the depth of the array
0527: * nesting. The encoding of element type names is as follows:
0528: *
0529: * <blockquote><table summary="Element types and encodings">
0530: * <tr><th> Element Type <th> <th> Encoding
0531: * <tr><td> boolean <td> <td align=center> Z
0532: * <tr><td> byte <td> <td align=center> B
0533: * <tr><td> char <td> <td align=center> C
0534: * <tr><td> class or interface
0535: * <td> <td align=center> L<i>classname</i>;
0536: * <tr><td> double <td> <td align=center> D
0537: * <tr><td> float <td> <td align=center> F
0538: * <tr><td> int <td> <td align=center> I
0539: * <tr><td> long <td> <td align=center> J
0540: * <tr><td> short <td> <td align=center> S
0541: * </table></blockquote>
0542: *
0543: * <p> The class or interface name <i>classname</i> is the binary name of
0544: * the class specified above.
0545: *
0546: * <p> Examples:
0547: * <blockquote><pre>
0548: * String.class.getName()
0549: * returns "java.lang.String"
0550: * byte.class.getName()
0551: * returns "byte"
0552: * (new Object[3]).getClass().getName()
0553: * returns "[Ljava.lang.Object;"
0554: * (new int[3][4][5][6][7][8][9]).getClass().getName()
0555: * returns "[[[[[[[I"
0556: * </pre></blockquote>
0557: *
0558: * @return the name of the class or interface
0559: * represented by this object.
0560: */
0561: public String getName() {
0562: if (name == null)
0563: name = getName0();
0564: return name;
0565: }
0566:
0567: // cache the name to reduce the number of calls into the VM
0568: private transient String name;
0569:
0570: private native String getName0();
0571:
0572: /**
0573: * Returns the class loader for the class. Some implementations may use
0574: * null to represent the bootstrap class loader. This method will return
0575: * null in such implementations if this class was loaded by the bootstrap
0576: * class loader.
0577: *
0578: * <p> If a security manager is present, and the caller's class loader is
0579: * not null and the caller's class loader is not the same as or an ancestor of
0580: * the class loader for the class whose class loader is requested, then
0581: * this method calls the security manager's {@code checkPermission}
0582: * method with a {@code RuntimePermission("getClassLoader")}
0583: * permission to ensure it's ok to access the class loader for the class.
0584: *
0585: * <p>If this object
0586: * represents a primitive type or void, null is returned.
0587: *
0588: * @return the class loader that loaded the class or interface
0589: * represented by this object.
0590: * @throws SecurityException
0591: * if a security manager exists and its
0592: * {@code checkPermission} method denies
0593: * access to the class loader for the class.
0594: * @see java.lang.ClassLoader
0595: * @see SecurityManager#checkPermission
0596: * @see java.lang.RuntimePermission
0597: */
0598: public ClassLoader getClassLoader() {
0599: ClassLoader cl = getClassLoader0();
0600: if (cl == null)
0601: return null;
0602: SecurityManager sm = System.getSecurityManager();
0603: if (sm != null) {
0604: ClassLoader ccl = ClassLoader.getCallerClassLoader();
0605: if (ccl != null && ccl != cl && !cl.isAncestor(ccl)) {
0606: sm
0607: .checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
0608: }
0609: }
0610: return cl;
0611: }
0612:
0613: // Package-private to allow ClassLoader access
0614: native ClassLoader getClassLoader0();
0615:
0616: /**
0617: * Returns an array of {@code TypeVariable} objects that represent the
0618: * type variables declared by the generic declaration represented by this
0619: * {@code GenericDeclaration} object, in declaration order. Returns an
0620: * array of length 0 if the underlying generic declaration declares no type
0621: * variables.
0622: *
0623: * @return an array of {@code TypeVariable} objects that represent
0624: * the type variables declared by this generic declaration
0625: * @throws GenericSignatureFormatError if the generic
0626: * signature of this generic declaration does not conform to
0627: * the format specified in the Java Virtual Machine Specification,
0628: * 3rd edition
0629: * @since 1.5
0630: */
0631: public TypeVariable<Class<T>>[] getTypeParameters() {
0632: if (getGenericSignature() != null)
0633: return (TypeVariable<Class<T>>[]) getGenericInfo()
0634: .getTypeParameters();
0635: else
0636: return (TypeVariable<Class<T>>[]) new TypeVariable[0];
0637: }
0638:
0639: /**
0640: * Returns the {@code Class} representing the superclass of the entity
0641: * (class, interface, primitive type or void) represented by this
0642: * {@code Class}. If this {@code Class} represents either the
0643: * {@code Object} class, an interface, a primitive type, or void, then
0644: * null is returned. If this object represents an array class then the
0645: * {@code Class} object representing the {@code Object} class is
0646: * returned.
0647: *
0648: * @return the superclass of the class represented by this object.
0649: */
0650: public native Class<? super T> getSuperclass();
0651:
0652: /**
0653: * Returns the {@code Type} representing the direct superclass of
0654: * the entity (class, interface, primitive type or void) represented by
0655: * this {@code Class}.
0656: *
0657: * <p>If the superclass is a parameterized type, the {@code Type}
0658: * object returned must accurately reflect the actual type
0659: * parameters used in the source code. The parameterized type
0660: * representing the superclass is created if it had not been
0661: * created before. See the declaration of {@link
0662: * java.lang.reflect.ParameterizedType ParameterizedType} for the
0663: * semantics of the creation process for parameterized types. If
0664: * this {@code Class} represents either the {@code Object}
0665: * class, an interface, a primitive type, or void, then null is
0666: * returned. If this object represents an array class then the
0667: * {@code Class} object representing the {@code Object} class is
0668: * returned.
0669: *
0670: * @throws GenericSignatureFormatError if the generic
0671: * class signature does not conform to the format specified in the
0672: * Java Virtual Machine Specification, 3rd edition
0673: * @throws TypeNotPresentException if the generic superclass
0674: * refers to a non-existent type declaration
0675: * @throws MalformedParameterizedTypeException if the
0676: * generic superclass refers to a parameterized type that cannot be
0677: * instantiated for any reason
0678: * @return the superclass of the class represented by this object
0679: * @since 1.5
0680: */
0681: public Type getGenericSuperclass() {
0682: if (getGenericSignature() != null) {
0683: // Historical irregularity:
0684: // Generic signature marks interfaces with superclass = Object
0685: // but this API returns null for interfaces
0686: if (isInterface())
0687: return null;
0688: return getGenericInfo().getSuperclass();
0689: } else
0690: return getSuperclass();
0691: }
0692:
0693: /**
0694: * Gets the package for this class. The class loader of this class is used
0695: * to find the package. If the class was loaded by the bootstrap class
0696: * loader the set of packages loaded from CLASSPATH is searched to find the
0697: * package of the class. Null is returned if no package object was created
0698: * by the class loader of this class.
0699: *
0700: * <p> Packages have attributes for versions and specifications only if the
0701: * information was defined in the manifests that accompany the classes, and
0702: * if the class loader created the package instance with the attributes
0703: * from the manifest.
0704: *
0705: * @return the package of the class, or null if no package
0706: * information is available from the archive or codebase.
0707: */
0708: public Package getPackage() {
0709: return Package.getPackage(this );
0710: }
0711:
0712: /**
0713: * Determines the interfaces implemented by the class or interface
0714: * represented by this object.
0715: *
0716: * <p> If this object represents a class, the return value is an array
0717: * containing objects representing all interfaces implemented by the
0718: * class. The order of the interface objects in the array corresponds to
0719: * the order of the interface names in the {@code implements} clause
0720: * of the declaration of the class represented by this object. For
0721: * example, given the declaration:
0722: * <blockquote>
0723: * {@code class Shimmer implements FloorWax, DessertTopping { ... }}
0724: * </blockquote>
0725: * suppose the value of {@code s} is an instance of
0726: * {@code Shimmer}; the value of the expression:
0727: * <blockquote>
0728: * {@code s.getClass().getInterfaces()[0]}
0729: * </blockquote>
0730: * is the {@code Class} object that represents interface
0731: * {@code FloorWax}; and the value of:
0732: * <blockquote>
0733: * {@code s.getClass().getInterfaces()[1]}
0734: * </blockquote>
0735: * is the {@code Class} object that represents interface
0736: * {@code DessertTopping}.
0737: *
0738: * <p> If this object represents an interface, the array contains objects
0739: * representing all interfaces extended by the interface. The order of the
0740: * interface objects in the array corresponds to the order of the interface
0741: * names in the {@code extends} clause of the declaration of the
0742: * interface represented by this object.
0743: *
0744: * <p> If this object represents a class or interface that implements no
0745: * interfaces, the method returns an array of length 0.
0746: *
0747: * <p> If this object represents a primitive type or void, the method
0748: * returns an array of length 0.
0749: *
0750: * @return an array of interfaces implemented by this class.
0751: */
0752: public native Class<?>[] getInterfaces();
0753:
0754: /**
0755: * Returns the {@code Type}s representing the interfaces
0756: * directly implemented by the class or interface represented by
0757: * this object.
0758: *
0759: * <p>If a superinterface is a parameterized type, the
0760: * {@code Type} object returned for it must accurately reflect
0761: * the actual type parameters used in the source code. The
0762: * parameterized type representing each superinterface is created
0763: * if it had not been created before. See the declaration of
0764: * {@link java.lang.reflect.ParameterizedType ParameterizedType}
0765: * for the semantics of the creation process for parameterized
0766: * types.
0767: *
0768: * <p> If this object represents a class, the return value is an
0769: * array containing objects representing all interfaces
0770: * implemented by the class. The order of the interface objects in
0771: * the array corresponds to the order of the interface names in
0772: * the {@code implements} clause of the declaration of the class
0773: * represented by this object. In the case of an array class, the
0774: * interfaces {@code Cloneable} and {@code Serializable} are
0775: * returned in that order.
0776: *
0777: * <p>If this object represents an interface, the array contains
0778: * objects representing all interfaces directly extended by the
0779: * interface. The order of the interface objects in the array
0780: * corresponds to the order of the interface names in the
0781: * {@code extends} clause of the declaration of the interface
0782: * represented by this object.
0783: *
0784: * <p>If this object represents a class or interface that
0785: * implements no interfaces, the method returns an array of length
0786: * 0.
0787: *
0788: * <p>If this object represents a primitive type or void, the
0789: * method returns an array of length 0.
0790: *
0791: * @throws GenericSignatureFormatError
0792: * if the generic class signature does not conform to the format
0793: * specified in the Java Virtual Machine Specification, 3rd edition
0794: * @throws TypeNotPresentException if any of the generic
0795: * superinterfaces refers to a non-existent type declaration
0796: * @throws MalformedParameterizedTypeException if any of the
0797: * generic superinterfaces refer to a parameterized type that cannot
0798: * be instantiated for any reason
0799: * @return an array of interfaces implemented by this class
0800: * @since 1.5
0801: */
0802: public Type[] getGenericInterfaces() {
0803: if (getGenericSignature() != null)
0804: return getGenericInfo().getSuperInterfaces();
0805: else
0806: return getInterfaces();
0807: }
0808:
0809: /**
0810: * Returns the {@code Class} representing the component type of an
0811: * array. If this class does not represent an array class this method
0812: * returns null.
0813: *
0814: * @return the {@code Class} representing the component type of this
0815: * class if this class is an array
0816: * @see java.lang.reflect.Array
0817: * @since JDK1.1
0818: */
0819: public native Class<?> getComponentType();
0820:
0821: /**
0822: * Returns the Java language modifiers for this class or interface, encoded
0823: * in an integer. The modifiers consist of the Java Virtual Machine's
0824: * constants for {@code public}, {@code protected},
0825: * {@code private}, {@code final}, {@code static},
0826: * {@code abstract} and {@code interface}; they should be decoded
0827: * using the methods of class {@code Modifier}.
0828: *
0829: * <p> If the underlying class is an array class, then its
0830: * {@code public}, {@code private} and {@code protected}
0831: * modifiers are the same as those of its component type. If this
0832: * {@code Class} represents a primitive type or void, its
0833: * {@code public} modifier is always {@code true}, and its
0834: * {@code protected} and {@code private} modifiers are always
0835: * {@code false}. If this object represents an array class, a
0836: * primitive type or void, then its {@code final} modifier is always
0837: * {@code true} and its interface modifier is always
0838: * {@code false}. The values of its other modifiers are not determined
0839: * by this specification.
0840: *
0841: * <p> The modifier encodings are defined in <em>The Java Virtual Machine
0842: * Specification</em>, table 4.1.
0843: *
0844: * @return the {@code int} representing the modifiers for this class
0845: * @see java.lang.reflect.Modifier
0846: * @since JDK1.1
0847: */
0848: public native int getModifiers();
0849:
0850: /**
0851: * Gets the signers of this class.
0852: *
0853: * @return the signers of this class, or null if there are no signers. In
0854: * particular, this method returns null if this object represents
0855: * a primitive type or void.
0856: * @since JDK1.1
0857: */
0858: public native Object[] getSigners();
0859:
0860: /**
0861: * Set the signers of this class.
0862: */
0863: native void setSigners(Object[] signers);
0864:
0865: /**
0866: * If this {@code Class} object represents a local or anonymous
0867: * class within a method, returns a {@link
0868: * java.lang.reflect.Method Method} object representing the
0869: * immediately enclosing method of the underlying class. Returns
0870: * {@code null} otherwise.
0871: *
0872: * In particular, this method returns {@code null} if the underlying
0873: * class is a local or anonymous class immediately enclosed by a type
0874: * declaration, instance initializer or static initializer.
0875: *
0876: * @return the immediately enclosing method of the underlying class, if
0877: * that class is a local or anonymous class; otherwise {@code null}.
0878: * @since 1.5
0879: */
0880: public Method getEnclosingMethod() {
0881: EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
0882:
0883: if (enclosingInfo == null)
0884: return null;
0885: else {
0886: if (!enclosingInfo.isMethod())
0887: return null;
0888:
0889: MethodRepository typeInfo = MethodRepository.make(
0890: enclosingInfo.getDescriptor(), getFactory());
0891: Class returnType = toClass(typeInfo.getReturnType());
0892: Type[] parameterTypes = typeInfo.getParameterTypes();
0893: Class<?>[] parameterClasses = new Class<?>[parameterTypes.length];
0894:
0895: // Convert Types to Classes; returned types *should*
0896: // be class objects since the methodDescriptor's used
0897: // don't have generics information
0898: for (int i = 0; i < parameterClasses.length; i++)
0899: parameterClasses[i] = toClass(parameterTypes[i]);
0900:
0901: /*
0902: * Loop over all declared methods; match method name,
0903: * number of and type of parameters, *and* return
0904: * type. Matching return type is also necessary
0905: * because of covariant returns, etc.
0906: */
0907: for (Method m : enclosingInfo.getEnclosingClass()
0908: .getDeclaredMethods()) {
0909: if (m.getName().equals(enclosingInfo.getName())) {
0910: Class<?>[] candidateParamClasses = m
0911: .getParameterTypes();
0912: if (candidateParamClasses.length == parameterClasses.length) {
0913: boolean matches = true;
0914: for (int i = 0; i < candidateParamClasses.length; i++) {
0915: if (!candidateParamClasses[i]
0916: .equals(parameterClasses[i])) {
0917: matches = false;
0918: break;
0919: }
0920: }
0921:
0922: if (matches) { // finally, check return type
0923: if (m.getReturnType().equals(returnType))
0924: return m;
0925: }
0926: }
0927: }
0928: }
0929:
0930: throw new InternalError("Enclosing method not found");
0931: }
0932: }
0933:
0934: private native Object[] getEnclosingMethod0();
0935:
0936: private EnclosingMethodInfo getEnclosingMethodInfo() {
0937: Object[] enclosingInfo = getEnclosingMethod0();
0938: if (enclosingInfo == null)
0939: return null;
0940: else {
0941: return new EnclosingMethodInfo(enclosingInfo);
0942: }
0943: }
0944:
0945: private final static class EnclosingMethodInfo {
0946: private Class<?> enclosingClass;
0947: private String name;
0948: private String descriptor;
0949:
0950: private EnclosingMethodInfo(Object[] enclosingInfo) {
0951: if (enclosingInfo.length != 3)
0952: throw new InternalError(
0953: "Malformed enclosing method information");
0954: try {
0955: // The array is expected to have three elements:
0956:
0957: // the immediately enclosing class
0958: enclosingClass = (Class<?>) enclosingInfo[0];
0959: assert (enclosingClass != null);
0960:
0961: // the immediately enclosing method or constructor's
0962: // name (can be null).
0963: name = (String) enclosingInfo[1];
0964:
0965: // the immediately enclosing method or constructor's
0966: // descriptor (null iff name is).
0967: descriptor = (String) enclosingInfo[2];
0968: assert ((name != null && descriptor != null) || name == descriptor);
0969: } catch (ClassCastException cce) {
0970: throw new InternalError(
0971: "Invalid type in enclosing method information");
0972: }
0973: }
0974:
0975: boolean isPartial() {
0976: return enclosingClass == null || name == null
0977: || descriptor == null;
0978: }
0979:
0980: boolean isConstructor() {
0981: return !isPartial() && "<init>".equals(name);
0982: }
0983:
0984: boolean isMethod() {
0985: return !isPartial() && !isConstructor()
0986: && !"<clinit>".equals(name);
0987: }
0988:
0989: Class<?> getEnclosingClass() {
0990: return enclosingClass;
0991: }
0992:
0993: String getName() {
0994: return name;
0995: }
0996:
0997: String getDescriptor() {
0998: return descriptor;
0999: }
1000:
1001: }
1002:
1003: private static Class toClass(Type o) {
1004: if (o instanceof GenericArrayType)
1005: return Array.newInstance(
1006: toClass(((GenericArrayType) o)
1007: .getGenericComponentType()), 0).getClass();
1008: return (Class) o;
1009: }
1010:
1011: /**
1012: * If this {@code Class} object represents a local or anonymous
1013: * class within a constructor, returns a {@link
1014: * java.lang.reflect.Constructor Constructor} object representing
1015: * the immediately enclosing constructor of the underlying
1016: * class. Returns {@code null} otherwise. In particular, this
1017: * method returns {@code null} if the underlying class is a local
1018: * or anonymous class immediately enclosed by a type declaration,
1019: * instance initializer or static initializer.
1020: *
1021: * @return the immediately enclosing constructor of the underlying class, if
1022: * that class is a local or anonymous class; otherwise {@code null}.
1023: * @since 1.5
1024: */
1025: public Constructor<?> getEnclosingConstructor() {
1026: EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
1027:
1028: if (enclosingInfo == null)
1029: return null;
1030: else {
1031: if (!enclosingInfo.isConstructor())
1032: return null;
1033:
1034: ConstructorRepository typeInfo = ConstructorRepository
1035: .make(enclosingInfo.getDescriptor(), getFactory());
1036: Type[] parameterTypes = typeInfo.getParameterTypes();
1037: Class<?>[] parameterClasses = new Class<?>[parameterTypes.length];
1038:
1039: // Convert Types to Classes; returned types *should*
1040: // be class objects since the methodDescriptor's used
1041: // don't have generics information
1042: for (int i = 0; i < parameterClasses.length; i++)
1043: parameterClasses[i] = toClass(parameterTypes[i]);
1044:
1045: /*
1046: * Loop over all declared constructors; match number
1047: * of and type of parameters.
1048: */
1049: for (Constructor c : enclosingInfo.getEnclosingClass()
1050: .getDeclaredConstructors()) {
1051: Class<?>[] candidateParamClasses = c
1052: .getParameterTypes();
1053: if (candidateParamClasses.length == parameterClasses.length) {
1054: boolean matches = true;
1055: for (int i = 0; i < candidateParamClasses.length; i++) {
1056: if (!candidateParamClasses[i]
1057: .equals(parameterClasses[i])) {
1058: matches = false;
1059: break;
1060: }
1061: }
1062:
1063: if (matches)
1064: return c;
1065: }
1066: }
1067:
1068: throw new InternalError("Enclosing constructor not found");
1069: }
1070: }
1071:
1072: /**
1073: * If the class or interface represented by this {@code Class} object
1074: * is a member of another class, returns the {@code Class} object
1075: * representing the class in which it was declared. This method returns
1076: * null if this class or interface is not a member of any other class. If
1077: * this {@code Class} object represents an array class, a primitive
1078: * type, or void,then this method returns null.
1079: *
1080: * @return the declaring class for this class
1081: * @since JDK1.1
1082: */
1083: public native Class<?> getDeclaringClass();
1084:
1085: /**
1086: * Returns the immediately enclosing class of the underlying
1087: * class. If the underlying class is a top level class this
1088: * method returns {@code null}.
1089: * @return the immediately enclosing class of the underlying class
1090: * @since 1.5
1091: */
1092: public Class<?> getEnclosingClass() {
1093: // There are five kinds of classes (or interfaces):
1094: // a) Top level classes
1095: // b) Nested classes (static member classes)
1096: // c) Inner classes (non-static member classes)
1097: // d) Local classes (named classes declared within a method)
1098: // e) Anonymous classes
1099:
1100: // JVM Spec 4.8.6: A class must have an EnclosingMethod
1101: // attribute if and only if it is a local class or an
1102: // anonymous class.
1103: EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
1104:
1105: if (enclosingInfo == null) {
1106: // This is a top level or a nested class or an inner class (a, b, or c)
1107: return getDeclaringClass();
1108: } else {
1109: Class<?> enclosingClass = enclosingInfo.getEnclosingClass();
1110: // This is a local class or an anonymous class (d or e)
1111: if (enclosingClass == this || enclosingClass == null)
1112: throw new InternalError(
1113: "Malformed enclosing method information");
1114: else
1115: return enclosingClass;
1116: }
1117: }
1118:
1119: /**
1120: * Returns the simple name of the underlying class as given in the
1121: * source code. Returns an empty string if the underlying class is
1122: * anonymous.
1123: *
1124: * <p>The simple name of an array is the simple name of the
1125: * component type with "[]" appended. In particular the simple
1126: * name of an array whose component type is anonymous is "[]".
1127: *
1128: * @return the simple name of the underlying class
1129: * @since 1.5
1130: */
1131: public String getSimpleName() {
1132: if (isArray())
1133: return getComponentType().getSimpleName() + "[]";
1134:
1135: String simpleName = getSimpleBinaryName();
1136: if (simpleName == null) { // top level class
1137: simpleName = getName();
1138: return simpleName
1139: .substring(simpleName.lastIndexOf(".") + 1); // strip the package name
1140: }
1141: // According to JLS3 "Binary Compatibility" (13.1) the binary
1142: // name of non-package classes (not top level) is the binary
1143: // name of the immediately enclosing class followed by a '$' followed by:
1144: // (for nested and inner classes): the simple name.
1145: // (for local classes): 1 or more digits followed by the simple name.
1146: // (for anonymous classes): 1 or more digits.
1147:
1148: // Since getSimpleBinaryName() will strip the binary name of
1149: // the immediatly enclosing class, we are now looking at a
1150: // string that matches the regular expression "\$[0-9]*"
1151: // followed by a simple name (considering the simple of an
1152: // anonymous class to be the empty string).
1153:
1154: // Remove leading "\$[0-9]*" from the name
1155: int length = simpleName.length();
1156: if (length < 1 || simpleName.charAt(0) != '$')
1157: throw new InternalError("Malformed class name");
1158: int index = 1;
1159: while (index < length && isAsciiDigit(simpleName.charAt(index)))
1160: index++;
1161: // Eventually, this is the empty string iff this is an anonymous class
1162: return simpleName.substring(index);
1163: }
1164:
1165: /**
1166: * Character.isDigit answers {@code true} to some non-ascii
1167: * digits. This one does not.
1168: */
1169: private static boolean isAsciiDigit(char c) {
1170: return '0' <= c && c <= '9';
1171: }
1172:
1173: /**
1174: * Returns the canonical name of the underlying class as
1175: * defined by the Java Language Specification. Returns null if
1176: * the underlying class does not have a canonical name (i.e., if
1177: * it is a local or anonymous class or an array whose component
1178: * type does not have a canonical name).
1179: * @return the canonical name of the underlying class if it exists, and
1180: * {@code null} otherwise.
1181: * @since 1.5
1182: */
1183: public String getCanonicalName() {
1184: if (isArray()) {
1185: String canonicalName = getComponentType()
1186: .getCanonicalName();
1187: if (canonicalName != null)
1188: return canonicalName + "[]";
1189: else
1190: return null;
1191: }
1192: if (isLocalOrAnonymousClass())
1193: return null;
1194: Class<?> enclosingClass = getEnclosingClass();
1195: if (enclosingClass == null) { // top level class
1196: return getName();
1197: } else {
1198: String enclosingName = enclosingClass.getCanonicalName();
1199: if (enclosingName == null)
1200: return null;
1201: return enclosingName + "." + getSimpleName();
1202: }
1203: }
1204:
1205: /**
1206: * Returns {@code true} if and only if the underlying class
1207: * is an anonymous class.
1208: *
1209: * @return {@code true} if and only if this class is an anonymous class.
1210: * @since 1.5
1211: */
1212: public boolean isAnonymousClass() {
1213: return "".equals(getSimpleName());
1214: }
1215:
1216: /**
1217: * Returns {@code true} if and only if the underlying class
1218: * is a local class.
1219: *
1220: * @return {@code true} if and only if this class is a local class.
1221: * @since 1.5
1222: */
1223: public boolean isLocalClass() {
1224: return isLocalOrAnonymousClass() && !isAnonymousClass();
1225: }
1226:
1227: /**
1228: * Returns {@code true} if and only if the underlying class
1229: * is a member class.
1230: *
1231: * @return {@code true} if and only if this class is a member class.
1232: * @since 1.5
1233: */
1234: public boolean isMemberClass() {
1235: return getSimpleBinaryName() != null
1236: && !isLocalOrAnonymousClass();
1237: }
1238:
1239: /**
1240: * Returns the "simple binary name" of the underlying class, i.e.,
1241: * the binary name without the leading enclosing class name.
1242: * Returns {@code null} if the underlying class is a top level
1243: * class.
1244: */
1245: private String getSimpleBinaryName() {
1246: Class<?> enclosingClass = getEnclosingClass();
1247: if (enclosingClass == null) // top level class
1248: return null;
1249: // Otherwise, strip the enclosing class' name
1250: try {
1251: return getName().substring(
1252: enclosingClass.getName().length());
1253: } catch (IndexOutOfBoundsException ex) {
1254: throw new InternalError("Malformed class name");
1255: }
1256: }
1257:
1258: /**
1259: * Returns {@code true} if this is a local class or an anonymous
1260: * class. Returns {@code false} otherwise.
1261: */
1262: private boolean isLocalOrAnonymousClass() {
1263: // JVM Spec 4.8.6: A class must have an EnclosingMethod
1264: // attribute if and only if it is a local class or an
1265: // anonymous class.
1266: return getEnclosingMethodInfo() != null;
1267: }
1268:
1269: /**
1270: * Returns an array containing {@code Class} objects representing all
1271: * the public classes and interfaces that are members of the class
1272: * represented by this {@code Class} object. This includes public
1273: * class and interface members inherited from superclasses and public class
1274: * and interface members declared by the class. This method returns an
1275: * array of length 0 if this {@code Class} object has no public member
1276: * classes or interfaces. This method also returns an array of length 0 if
1277: * this {@code Class} object represents a primitive type, an array
1278: * class, or void.
1279: *
1280: * @return the array of {@code Class} objects representing the public
1281: * members of this class
1282: * @exception SecurityException
1283: * If a security manager, <i>s</i>, is present and any of the
1284: * following conditions is met:
1285: *
1286: * <ul>
1287: *
1288: * <li> invocation of
1289: * {@link SecurityManager#checkMemberAccess
1290: * s.checkMemberAccess(this, Member.PUBLIC)} method
1291: * denies access to the classes within this class
1292: *
1293: * <li> the caller's class loader is not the same as or an
1294: * ancestor of the class loader for the current class and
1295: * invocation of {@link SecurityManager#checkPackageAccess
1296: * s.checkPackageAccess()} denies access to the package
1297: * of this class
1298: *
1299: * </ul>
1300: *
1301: * @since JDK1.1
1302: */
1303: public Class<?>[] getClasses() {
1304: // be very careful not to change the stack depth of this
1305: // checkMemberAccess call for security reasons
1306: // see java.lang.SecurityManager.checkMemberAccess
1307: checkMemberAccess(Member.PUBLIC, ClassLoader
1308: .getCallerClassLoader());
1309:
1310: // Privileged so this implementation can look at DECLARED classes,
1311: // something the caller might not have privilege to do. The code here
1312: // is allowed to look at DECLARED classes because (1) it does not hand
1313: // out anything other than public members and (2) public member access
1314: // has already been ok'd by the SecurityManager.
1315:
1316: Class[] result = (Class[]) java.security.AccessController
1317: .doPrivileged(new java.security.PrivilegedAction() {
1318: public Object run() {
1319: java.util.List<Class> list = new java.util.ArrayList();
1320: Class currentClass = Class.this ;
1321: while (currentClass != null) {
1322: Class[] members = currentClass
1323: .getDeclaredClasses();
1324: for (int i = 0; i < members.length; i++) {
1325: if (Modifier.isPublic(members[i]
1326: .getModifiers())) {
1327: list.add(members[i]);
1328: }
1329: }
1330: currentClass = currentClass.getSuperclass();
1331: }
1332: Class[] empty = {};
1333: return list.toArray(empty);
1334: }
1335: });
1336:
1337: return result;
1338: }
1339:
1340: /**
1341: * Returns an array containing {@code Field} objects reflecting all
1342: * the accessible public fields of the class or interface represented by
1343: * this {@code Class} object. The elements in the array returned are
1344: * not sorted and are not in any particular order. This method returns an
1345: * array of length 0 if the class or interface has no accessible public
1346: * fields, or if it represents an array class, a primitive type, or void.
1347: *
1348: * <p> Specifically, if this {@code Class} object represents a class,
1349: * this method returns the public fields of this class and of all its
1350: * superclasses. If this {@code Class} object represents an
1351: * interface, this method returns the fields of this interface and of all
1352: * its superinterfaces.
1353: *
1354: * <p> The implicit length field for array class is not reflected by this
1355: * method. User code should use the methods of class {@code Array} to
1356: * manipulate arrays.
1357: *
1358: * <p> See <em>The Java Language Specification</em>, sections 8.2 and 8.3.
1359: *
1360: * @return the array of {@code Field} objects representing the
1361: * public fields
1362: * @exception SecurityException
1363: * If a security manager, <i>s</i>, is present and any of the
1364: * following conditions is met:
1365: *
1366: * <ul>
1367: *
1368: * <li> invocation of
1369: * {@link SecurityManager#checkMemberAccess
1370: * s.checkMemberAccess(this, Member.PUBLIC)} denies
1371: * access to the fields within this class
1372: *
1373: * <li> the caller's class loader is not the same as or an
1374: * ancestor of the class loader for the current class and
1375: * invocation of {@link SecurityManager#checkPackageAccess
1376: * s.checkPackageAccess()} denies access to the package
1377: * of this class
1378: *
1379: * </ul>
1380: *
1381: * @since JDK1.1
1382: */
1383: public Field[] getFields() throws SecurityException {
1384: // be very careful not to change the stack depth of this
1385: // checkMemberAccess call for security reasons
1386: // see java.lang.SecurityManager.checkMemberAccess
1387: checkMemberAccess(Member.PUBLIC, ClassLoader
1388: .getCallerClassLoader());
1389: return copyFields(privateGetPublicFields(null));
1390: }
1391:
1392: /**
1393: * Returns an array containing {@code Method} objects reflecting all
1394: * the public <em>member</em> methods of the class or interface represented
1395: * by this {@code Class} object, including those declared by the class
1396: * or interface and those inherited from superclasses and
1397: * superinterfaces. Array classes return all the (public) member methods
1398: * inherited from the {@code Object} class. The elements in the array
1399: * returned are not sorted and are not in any particular order. This
1400: * method returns an array of length 0 if this {@code Class} object
1401: * represents a class or interface that has no public member methods, or if
1402: * this {@code Class} object represents a primitive type or void.
1403: *
1404: * <p> The class initialization method {@code <clinit>} is not
1405: * included in the returned array. If the class declares multiple public
1406: * member methods with the same parameter types, they are all included in
1407: * the returned array.
1408: *
1409: * <p> See <em>The Java Language Specification</em>, sections 8.2 and 8.4.
1410: *
1411: * @return the array of {@code Method} objects representing the
1412: * public methods of this class
1413: * @exception SecurityException
1414: * If a security manager, <i>s</i>, is present and any of the
1415: * following conditions is met:
1416: *
1417: * <ul>
1418: *
1419: * <li> invocation of
1420: * {@link SecurityManager#checkMemberAccess
1421: * s.checkMemberAccess(this, Member.PUBLIC)} denies
1422: * access to the methods within this class
1423: *
1424: * <li> the caller's class loader is not the same as or an
1425: * ancestor of the class loader for the current class and
1426: * invocation of {@link SecurityManager#checkPackageAccess
1427: * s.checkPackageAccess()} denies access to the package
1428: * of this class
1429: *
1430: * </ul>
1431: *
1432: * @since JDK1.1
1433: */
1434: public Method[] getMethods() throws SecurityException {
1435: // be very careful not to change the stack depth of this
1436: // checkMemberAccess call for security reasons
1437: // see java.lang.SecurityManager.checkMemberAccess
1438: checkMemberAccess(Member.PUBLIC, ClassLoader
1439: .getCallerClassLoader());
1440: return copyMethods(privateGetPublicMethods());
1441: }
1442:
1443: /**
1444: * Returns an array containing {@code Constructor} objects reflecting
1445: * all the public constructors of the class represented by this
1446: * {@code Class} object. An array of length 0 is returned if the
1447: * class has no public constructors, or if the class is an array class, or
1448: * if the class reflects a primitive type or void.
1449: *
1450: * Note that while this method returns an array of {@code
1451: * Constructor<T>} objects (that is an array of constructors from
1452: * this class), the return type of this method is {@code
1453: * Constructor<?>[]} and <em>not</em> {@code Constructor<T>[]} as
1454: * might be expected. This less informative return type is
1455: * necessary since after being returned from this method, the
1456: * array could be modified to hold {@code Constructor} objects for
1457: * different classes, which would violate the type guarantees of
1458: * {@code Constructor<T>[]}.
1459: *
1460: * @return the array of {@code Constructor} objects representing the
1461: * public constructors of this class
1462: * @exception SecurityException
1463: * If a security manager, <i>s</i>, is present and any of the
1464: * following conditions is met:
1465: *
1466: * <ul>
1467: *
1468: * <li> invocation of
1469: * {@link SecurityManager#checkMemberAccess
1470: * s.checkMemberAccess(this, Member.PUBLIC)} denies
1471: * access to the constructors within this class
1472: *
1473: * <li> the caller's class loader is not the same as or an
1474: * ancestor of the class loader for the current class and
1475: * invocation of {@link SecurityManager#checkPackageAccess
1476: * s.checkPackageAccess()} denies access to the package
1477: * of this class
1478: *
1479: * </ul>
1480: *
1481: * @since JDK1.1
1482: */
1483: public Constructor<?>[] getConstructors() throws SecurityException {
1484: // be very careful not to change the stack depth of this
1485: // checkMemberAccess call for security reasons
1486: // see java.lang.SecurityManager.checkMemberAccess
1487: checkMemberAccess(Member.PUBLIC, ClassLoader
1488: .getCallerClassLoader());
1489: return copyConstructors(privateGetDeclaredConstructors(true));
1490: }
1491:
1492: /**
1493: * Returns a {@code Field} object that reflects the specified public
1494: * member field of the class or interface represented by this
1495: * {@code Class} object. The {@code name} parameter is a
1496: * {@code String} specifying the simple name of the desired field.
1497: *
1498: * <p> The field to be reflected is determined by the algorithm that
1499: * follows. Let C be the class represented by this object:
1500: * <OL>
1501: * <LI> If C declares a public field with the name specified, that is the
1502: * field to be reflected.</LI>
1503: * <LI> If no field was found in step 1 above, this algorithm is applied
1504: * recursively to each direct superinterface of C. The direct
1505: * superinterfaces are searched in the order they were declared.</LI>
1506: * <LI> If no field was found in steps 1 and 2 above, and C has a
1507: * superclass S, then this algorithm is invoked recursively upon S.
1508: * If C has no superclass, then a {@code NoSuchFieldException}
1509: * is thrown.</LI>
1510: * </OL>
1511: *
1512: * <p> See <em>The Java Language Specification</em>, sections 8.2 and 8.3.
1513: *
1514: * @param name the field name
1515: * @return the {@code Field} object of this class specified by
1516: * {@code name}
1517: * @exception NoSuchFieldException if a field with the specified name is
1518: * not found.
1519: * @exception NullPointerException if {@code name} is {@code null}
1520: * @exception SecurityException
1521: * If a security manager, <i>s</i>, is present and any of the
1522: * following conditions is met:
1523: *
1524: * <ul>
1525: *
1526: * <li> invocation of
1527: * {@link SecurityManager#checkMemberAccess
1528: * s.checkMemberAccess(this, Member.PUBLIC)} denies
1529: * access to the field
1530: *
1531: * <li> the caller's class loader is not the same as or an
1532: * ancestor of the class loader for the current class and
1533: * invocation of {@link SecurityManager#checkPackageAccess
1534: * s.checkPackageAccess()} denies access to the package
1535: * of this class
1536: *
1537: * </ul>
1538: *
1539: * @since JDK1.1
1540: */
1541: public Field getField(String name) throws NoSuchFieldException,
1542: SecurityException {
1543: // be very careful not to change the stack depth of this
1544: // checkMemberAccess call for security reasons
1545: // see java.lang.SecurityManager.checkMemberAccess
1546: checkMemberAccess(Member.PUBLIC, ClassLoader
1547: .getCallerClassLoader());
1548: Field field = getField0(name);
1549: if (field == null) {
1550: throw new NoSuchFieldException(name);
1551: }
1552: return field;
1553: }
1554:
1555: /**
1556: * Returns a {@code Method} object that reflects the specified public
1557: * member method of the class or interface represented by this
1558: * {@code Class} object. The {@code name} parameter is a
1559: * {@code String} specifying the simple name of the desired method. The
1560: * {@code parameterTypes} parameter is an array of {@code Class}
1561: * objects that identify the method's formal parameter types, in declared
1562: * order. If {@code parameterTypes} is {@code null}, it is
1563: * treated as if it were an empty array.
1564: *
1565: * <p> If the {@code name} is "{@code <init>};"or "{@code <clinit>}" a
1566: * {@code NoSuchMethodException} is raised. Otherwise, the method to
1567: * be reflected is determined by the algorithm that follows. Let C be the
1568: * class represented by this object:
1569: * <OL>
1570: * <LI> C is searched for any <I>matching methods</I>. If no matching
1571: * method is found, the algorithm of step 1 is invoked recursively on
1572: * the superclass of C.</LI>
1573: * <LI> If no method was found in step 1 above, the superinterfaces of C
1574: * are searched for a matching method. If any such method is found, it
1575: * is reflected.</LI>
1576: * </OL>
1577: *
1578: * To find a matching method in a class C: If C declares exactly one
1579: * public method with the specified name and exactly the same formal
1580: * parameter types, that is the method reflected. If more than one such
1581: * method is found in C, and one of these methods has a return type that is
1582: * more specific than any of the others, that method is reflected;
1583: * otherwise one of the methods is chosen arbitrarily.
1584: *
1585: * <p>Note that there may be more than one matching method in a
1586: * class because while the Java language forbids a class to
1587: * declare multiple methods with the same signature but different
1588: * return types, the Java virtual machine does not. This
1589: * increased flexibility in the virtual machine can be used to
1590: * implement various language features. For example, covariant
1591: * returns can be implemented with {@linkplain
1592: * java.lang.reflect.Method#isBridge bridge methods}; the bridge
1593: * method and the method being overridden would have the same
1594: * signature but different return types.
1595: *
1596: * <p> See <em>The Java Language Specification</em>, sections 8.2 and 8.4.
1597: *
1598: * @param name the name of the method
1599: * @param parameterTypes the list of parameters
1600: * @return the {@code Method} object that matches the specified
1601: * {@code name} and {@code parameterTypes}
1602: * @exception NoSuchMethodException if a matching method is not found
1603: * or if the name is "<init>"or "<clinit>".
1604: * @exception NullPointerException if {@code name} is {@code null}
1605: * @exception SecurityException
1606: * If a security manager, <i>s</i>, is present and any of the
1607: * following conditions is met:
1608: *
1609: * <ul>
1610: *
1611: * <li> invocation of
1612: * {@link SecurityManager#checkMemberAccess
1613: * s.checkMemberAccess(this, Member.PUBLIC)} denies
1614: * access to the method
1615: *
1616: * <li> the caller's class loader is not the same as or an
1617: * ancestor of the class loader for the current class and
1618: * invocation of {@link SecurityManager#checkPackageAccess
1619: * s.checkPackageAccess()} denies access to the package
1620: * of this class
1621: *
1622: * </ul>
1623: *
1624: * @since JDK1.1
1625: */
1626: public Method getMethod(String name, Class<?>... parameterTypes)
1627: throws NoSuchMethodException, SecurityException {
1628: // be very careful not to change the stack depth of this
1629: // checkMemberAccess call for security reasons
1630: // see java.lang.SecurityManager.checkMemberAccess
1631: checkMemberAccess(Member.PUBLIC, ClassLoader
1632: .getCallerClassLoader());
1633: Method method = getMethod0(name, parameterTypes);
1634: if (method == null) {
1635: throw new NoSuchMethodException(getName() + "." + name
1636: + argumentTypesToString(parameterTypes));
1637: }
1638: return method;
1639: }
1640:
1641: /**
1642: * Returns a {@code Constructor} object that reflects the specified
1643: * public constructor of the class represented by this {@code Class}
1644: * object. The {@code parameterTypes} parameter is an array of
1645: * {@code Class} objects that identify the constructor's formal
1646: * parameter types, in declared order.
1647: *
1648: * If this {@code Class} object represents an inner class
1649: * declared in a non-static context, the formal parameter types
1650: * include the explicit enclosing instance as the first parameter.
1651: *
1652: * <p> The constructor to reflect is the public constructor of the class
1653: * represented by this {@code Class} object whose formal parameter
1654: * types match those specified by {@code parameterTypes}.
1655: *
1656: * @param parameterTypes the parameter array
1657: * @return the {@code Constructor} object of the public constructor that
1658: * matches the specified {@code parameterTypes}
1659: * @exception NoSuchMethodException if a matching method is not found.
1660: * @exception SecurityException
1661: * If a security manager, <i>s</i>, is present and any of the
1662: * following conditions is met:
1663: *
1664: * <ul>
1665: *
1666: * <li> invocation of
1667: * {@link SecurityManager#checkMemberAccess
1668: * s.checkMemberAccess(this, Member.PUBLIC)} denies
1669: * access to the constructor
1670: *
1671: * <li> the caller's class loader is not the same as or an
1672: * ancestor of the class loader for the current class and
1673: * invocation of {@link SecurityManager#checkPackageAccess
1674: * s.checkPackageAccess()} denies access to the package
1675: * of this class
1676: *
1677: * </ul>
1678: *
1679: * @since JDK1.1
1680: */
1681: public Constructor<T> getConstructor(Class<?>... parameterTypes)
1682: throws NoSuchMethodException, SecurityException {
1683: // be very careful not to change the stack depth of this
1684: // checkMemberAccess call for security reasons
1685: // see java.lang.SecurityManager.checkMemberAccess
1686: checkMemberAccess(Member.PUBLIC, ClassLoader
1687: .getCallerClassLoader());
1688: return getConstructor0(parameterTypes, Member.PUBLIC);
1689: }
1690:
1691: /**
1692: * Returns an array of {@code Class} objects reflecting all the
1693: * classes and interfaces declared as members of the class represented by
1694: * this {@code Class} object. This includes public, protected, default
1695: * (package) access, and private classes and interfaces declared by the
1696: * class, but excludes inherited classes and interfaces. This method
1697: * returns an array of length 0 if the class declares no classes or
1698: * interfaces as members, or if this {@code Class} object represents a
1699: * primitive type, an array class, or void.
1700: *
1701: * @return the array of {@code Class} objects representing all the
1702: * declared members of this class
1703: * @exception SecurityException
1704: * If a security manager, <i>s</i>, is present and any of the
1705: * following conditions is met:
1706: *
1707: * <ul>
1708: *
1709: * <li> invocation of
1710: * {@link SecurityManager#checkMemberAccess
1711: * s.checkMemberAccess(this, Member.DECLARED)} denies
1712: * access to the declared classes within this class
1713: *
1714: * <li> the caller's class loader is not the same as or an
1715: * ancestor of the class loader for the current class and
1716: * invocation of {@link SecurityManager#checkPackageAccess
1717: * s.checkPackageAccess()} denies access to the package
1718: * of this class
1719: *
1720: * </ul>
1721: *
1722: * @since JDK1.1
1723: */
1724: public Class<?>[] getDeclaredClasses() throws SecurityException {
1725: // be very careful not to change the stack depth of this
1726: // checkMemberAccess call for security reasons
1727: // see java.lang.SecurityManager.checkMemberAccess
1728: checkMemberAccess(Member.DECLARED, ClassLoader
1729: .getCallerClassLoader());
1730: return getDeclaredClasses0();
1731: }
1732:
1733: /**
1734: * Returns an array of {@code Field} objects reflecting all the fields
1735: * declared by the class or interface represented by this
1736: * {@code Class} object. This includes public, protected, default
1737: * (package) access, and private fields, but excludes inherited fields.
1738: * The elements in the array returned are not sorted and are not in any
1739: * particular order. This method returns an array of length 0 if the class
1740: * or interface declares no fields, or if this {@code Class} object
1741: * represents a primitive type, an array class, or void.
1742: *
1743: * <p> See <em>The Java Language Specification</em>, sections 8.2 and 8.3.
1744: *
1745: * @return the array of {@code Field} objects representing all the
1746: * declared fields of this class
1747: * @exception SecurityException
1748: * If a security manager, <i>s</i>, is present and any of the
1749: * following conditions is met:
1750: *
1751: * <ul>
1752: *
1753: * <li> invocation of
1754: * {@link SecurityManager#checkMemberAccess
1755: * s.checkMemberAccess(this, Member.DECLARED)} denies
1756: * access to the declared fields within this class
1757: *
1758: * <li> the caller's class loader is not the same as or an
1759: * ancestor of the class loader for the current class and
1760: * invocation of {@link SecurityManager#checkPackageAccess
1761: * s.checkPackageAccess()} denies access to the package
1762: * of this class
1763: *
1764: * </ul>
1765: *
1766: * @since JDK1.1
1767: */
1768: public Field[] getDeclaredFields() throws SecurityException {
1769: // be very careful not to change the stack depth of this
1770: // checkMemberAccess call for security reasons
1771: // see java.lang.SecurityManager.checkMemberAccess
1772: checkMemberAccess(Member.DECLARED, ClassLoader
1773: .getCallerClassLoader());
1774: return copyFields(privateGetDeclaredFields(false));
1775: }
1776:
1777: /**
1778: * Returns an array of {@code Method} objects reflecting all the
1779: * methods declared by the class or interface represented by this
1780: * {@code Class} object. This includes public, protected, default
1781: * (package) access, and private methods, but excludes inherited methods.
1782: * The elements in the array returned are not sorted and are not in any
1783: * particular order. This method returns an array of length 0 if the class
1784: * or interface declares no methods, or if this {@code Class} object
1785: * represents a primitive type, an array class, or void. The class
1786: * initialization method {@code <clinit>} is not included in the
1787: * returned array. If the class declares multiple public member methods
1788: * with the same parameter types, they are all included in the returned
1789: * array.
1790: *
1791: * <p> See <em>The Java Language Specification</em>, section 8.2.
1792: *
1793: * @return the array of {@code Method} objects representing all the
1794: * declared methods of this class
1795: * @exception SecurityException
1796: * If a security manager, <i>s</i>, is present and any of the
1797: * following conditions is met:
1798: *
1799: * <ul>
1800: *
1801: * <li> invocation of
1802: * {@link SecurityManager#checkMemberAccess
1803: * s.checkMemberAccess(this, Member.DECLARED)} denies
1804: * access to the declared methods within this class
1805: *
1806: * <li> the caller's class loader is not the same as or an
1807: * ancestor of the class loader for the current class and
1808: * invocation of {@link SecurityManager#checkPackageAccess
1809: * s.checkPackageAccess()} denies access to the package
1810: * of this class
1811: *
1812: * </ul>
1813: *
1814: * @since JDK1.1
1815: */
1816: public Method[] getDeclaredMethods() throws SecurityException {
1817: // be very careful not to change the stack depth of this
1818: // checkMemberAccess call for security reasons
1819: // see java.lang.SecurityManager.checkMemberAccess
1820: checkMemberAccess(Member.DECLARED, ClassLoader
1821: .getCallerClassLoader());
1822: return copyMethods(privateGetDeclaredMethods(false));
1823: }
1824:
1825: /**
1826: * Returns an array of {@code Constructor} objects reflecting all the
1827: * constructors declared by the class represented by this
1828: * {@code Class} object. These are public, protected, default
1829: * (package) access, and private constructors. The elements in the array
1830: * returned are not sorted and are not in any particular order. If the
1831: * class has a default constructor, it is included in the returned array.
1832: * This method returns an array of length 0 if this {@code Class}
1833: * object represents an interface, a primitive type, an array class, or
1834: * void.
1835: *
1836: * <p> See <em>The Java Language Specification</em>, section 8.2.
1837: *
1838: * @return the array of {@code Constructor} objects representing all the
1839: * declared constructors of this class
1840: * @exception SecurityException
1841: * If a security manager, <i>s</i>, is present and any of the
1842: * following conditions is met:
1843: *
1844: * <ul>
1845: *
1846: * <li> invocation of
1847: * {@link SecurityManager#checkMemberAccess
1848: * s.checkMemberAccess(this, Member.DECLARED)} denies
1849: * access to the declared constructors within this class
1850: *
1851: * <li> the caller's class loader is not the same as or an
1852: * ancestor of the class loader for the current class and
1853: * invocation of {@link SecurityManager#checkPackageAccess
1854: * s.checkPackageAccess()} denies access to the package
1855: * of this class
1856: *
1857: * </ul>
1858: *
1859: * @since JDK1.1
1860: */
1861: public Constructor<?>[] getDeclaredConstructors()
1862: throws SecurityException {
1863: // be very careful not to change the stack depth of this
1864: // checkMemberAccess call for security reasons
1865: // see java.lang.SecurityManager.checkMemberAccess
1866: checkMemberAccess(Member.DECLARED, ClassLoader
1867: .getCallerClassLoader());
1868: return copyConstructors(privateGetDeclaredConstructors(false));
1869: }
1870:
1871: /**
1872: * Returns a {@code Field} object that reflects the specified declared
1873: * field of the class or interface represented by this {@code Class}
1874: * object. The {@code name} parameter is a {@code String} that
1875: * specifies the simple name of the desired field. Note that this method
1876: * will not reflect the {@code length} field of an array class.
1877: *
1878: * @param name the name of the field
1879: * @return the {@code Field} object for the specified field in this
1880: * class
1881: * @exception NoSuchFieldException if a field with the specified name is
1882: * not found.
1883: * @exception NullPointerException if {@code name} is {@code null}
1884: * @exception SecurityException
1885: * If a security manager, <i>s</i>, is present and any of the
1886: * following conditions is met:
1887: *
1888: * <ul>
1889: *
1890: * <li> invocation of
1891: * {@link SecurityManager#checkMemberAccess
1892: * s.checkMemberAccess(this, Member.DECLARED)} denies
1893: * access to the declared field
1894: *
1895: * <li> the caller's class loader is not the same as or an
1896: * ancestor of the class loader for the current class and
1897: * invocation of {@link SecurityManager#checkPackageAccess
1898: * s.checkPackageAccess()} denies access to the package
1899: * of this class
1900: *
1901: * </ul>
1902: *
1903: * @since JDK1.1
1904: */
1905: public Field getDeclaredField(String name)
1906: throws NoSuchFieldException, SecurityException {
1907: // be very careful not to change the stack depth of this
1908: // checkMemberAccess call for security reasons
1909: // see java.lang.SecurityManager.checkMemberAccess
1910: checkMemberAccess(Member.DECLARED, ClassLoader
1911: .getCallerClassLoader());
1912: Field field = searchFields(privateGetDeclaredFields(false),
1913: name);
1914: if (field == null) {
1915: throw new NoSuchFieldException(name);
1916: }
1917: return field;
1918: }
1919:
1920: /**
1921: * Returns a {@code Method} object that reflects the specified
1922: * declared method of the class or interface represented by this
1923: * {@code Class} object. The {@code name} parameter is a
1924: * {@code String} that specifies the simple name of the desired
1925: * method, and the {@code parameterTypes} parameter is an array of
1926: * {@code Class} objects that identify the method's formal parameter
1927: * types, in declared order. If more than one method with the same
1928: * parameter types is declared in a class, and one of these methods has a
1929: * return type that is more specific than any of the others, that method is
1930: * returned; otherwise one of the methods is chosen arbitrarily. If the
1931: * name is "<init>"or "<clinit>" a {@code NoSuchMethodException}
1932: * is raised.
1933: *
1934: * @param name the name of the method
1935: * @param parameterTypes the parameter array
1936: * @return the {@code Method} object for the method of this class
1937: * matching the specified name and parameters
1938: * @exception NoSuchMethodException if a matching method is not found.
1939: * @exception NullPointerException if {@code name} is {@code null}
1940: * @exception SecurityException
1941: * If a security manager, <i>s</i>, is present and any of the
1942: * following conditions is met:
1943: *
1944: * <ul>
1945: *
1946: * <li> invocation of
1947: * {@link SecurityManager#checkMemberAccess
1948: * s.checkMemberAccess(this, Member.DECLARED)} denies
1949: * access to the declared method
1950: *
1951: * <li> the caller's class loader is not the same as or an
1952: * ancestor of the class loader for the current class and
1953: * invocation of {@link SecurityManager#checkPackageAccess
1954: * s.checkPackageAccess()} denies access to the package
1955: * of this class
1956: *
1957: * </ul>
1958: *
1959: * @since JDK1.1
1960: */
1961: public Method getDeclaredMethod(String name,
1962: Class<?>... parameterTypes) throws NoSuchMethodException,
1963: SecurityException {
1964: // be very careful not to change the stack depth of this
1965: // checkMemberAccess call for security reasons
1966: // see java.lang.SecurityManager.checkMemberAccess
1967: checkMemberAccess(Member.DECLARED, ClassLoader
1968: .getCallerClassLoader());
1969: Method method = searchMethods(privateGetDeclaredMethods(false),
1970: name, parameterTypes);
1971: if (method == null) {
1972: throw new NoSuchMethodException(getName() + "." + name
1973: + argumentTypesToString(parameterTypes));
1974: }
1975: return method;
1976: }
1977:
1978: /**
1979: * Returns a {@code Constructor} object that reflects the specified
1980: * constructor of the class or interface represented by this
1981: * {@code Class} object. The {@code parameterTypes} parameter is
1982: * an array of {@code Class} objects that identify the constructor's
1983: * formal parameter types, in declared order.
1984: *
1985: * If this {@code Class} object represents an inner class
1986: * declared in a non-static context, the formal parameter types
1987: * include the explicit enclosing instance as the first parameter.
1988: *
1989: * @param parameterTypes the parameter array
1990: * @return The {@code Constructor} object for the constructor with the
1991: * specified parameter list
1992: * @exception NoSuchMethodException if a matching method is not found.
1993: * @exception SecurityException
1994: * If a security manager, <i>s</i>, is present and any of the
1995: * following conditions is met:
1996: *
1997: * <ul>
1998: *
1999: * <li> invocation of
2000: * {@link SecurityManager#checkMemberAccess
2001: * s.checkMemberAccess(this, Member.DECLARED)} denies
2002: * access to the declared constructor
2003: *
2004: * <li> the caller's class loader is not the same as or an
2005: * ancestor of the class loader for the current class and
2006: * invocation of {@link SecurityManager#checkPackageAccess
2007: * s.checkPackageAccess()} denies access to the package
2008: * of this class
2009: *
2010: * </ul>
2011: *
2012: * @since JDK1.1
2013: */
2014: public Constructor<T> getDeclaredConstructor(
2015: Class<?>... parameterTypes) throws NoSuchMethodException,
2016: SecurityException {
2017: // be very careful not to change the stack depth of this
2018: // checkMemberAccess call for security reasons
2019: // see java.lang.SecurityManager.checkMemberAccess
2020: checkMemberAccess(Member.DECLARED, ClassLoader
2021: .getCallerClassLoader());
2022: return getConstructor0(parameterTypes, Member.DECLARED);
2023: }
2024:
2025: /**
2026: * Finds a resource with a given name. The rules for searching resources
2027: * associated with a given class are implemented by the defining
2028: * {@linkplain ClassLoader class loader} of the class. This method
2029: * delegates to this object's class loader. If this object was loaded by
2030: * the bootstrap class loader, the method delegates to {@link
2031: * ClassLoader#getSystemResourceAsStream}.
2032: *
2033: * <p> Before delegation, an absolute resource name is constructed from the
2034: * given resource name using this algorithm:
2035: *
2036: * <ul>
2037: *
2038: * <li> If the {@code name} begins with a {@code '/'}
2039: * (<tt>'\u002f'</tt>), then the absolute name of the resource is the
2040: * portion of the {@code name} following the {@code '/'}.
2041: *
2042: * <li> Otherwise, the absolute name is of the following form:
2043: *
2044: * <blockquote>
2045: * {@code modified_package_name/name}
2046: * </blockquote>
2047: *
2048: * <p> Where the {@code modified_package_name} is the package name of this
2049: * object with {@code '/'} substituted for {@code '.'}
2050: * (<tt>'\u002e'</tt>).
2051: *
2052: * </ul>
2053: *
2054: * @param name name of the desired resource
2055: * @return A {@link java.io.InputStream} object or {@code null} if
2056: * no resource with this name is found
2057: * @throws NullPointerException If {@code name} is {@code null}
2058: * @since JDK1.1
2059: */
2060: public InputStream getResourceAsStream(String name) {
2061: name = resolveName(name);
2062: ClassLoader cl = getClassLoader0();
2063: if (cl == null) {
2064: // A system class.
2065: return ClassLoader.getSystemResourceAsStream(name);
2066: }
2067: return cl.getResourceAsStream(name);
2068: }
2069:
2070: /**
2071: * Finds a resource with a given name. The rules for searching resources
2072: * associated with a given class are implemented by the defining
2073: * {@linkplain ClassLoader class loader} of the class. This method
2074: * delegates to this object's class loader. If this object was loaded by
2075: * the bootstrap class loader, the method delegates to {@link
2076: * ClassLoader#getSystemResource}.
2077: *
2078: * <p> Before delegation, an absolute resource name is constructed from the
2079: * given resource name using this algorithm:
2080: *
2081: * <ul>
2082: *
2083: * <li> If the {@code name} begins with a {@code '/'}
2084: * (<tt>'\u002f'</tt>), then the absolute name of the resource is the
2085: * portion of the {@code name} following the {@code '/'}.
2086: *
2087: * <li> Otherwise, the absolute name is of the following form:
2088: *
2089: * <blockquote>
2090: * {@code modified_package_name/name}
2091: * </blockquote>
2092: *
2093: * <p> Where the {@code modified_package_name} is the package name of this
2094: * object with {@code '/'} substituted for {@code '.'}
2095: * (<tt>'\u002e'</tt>).
2096: *
2097: * </ul>
2098: *
2099: * @param name name of the desired resource
2100: * @return A {@link java.net.URL} object or {@code null} if no
2101: * resource with this name is found
2102: * @since JDK1.1
2103: */
2104: public java.net.URL getResource(String name) {
2105: name = resolveName(name);
2106: ClassLoader cl = getClassLoader0();
2107: if (cl == null) {
2108: // A system class.
2109: return ClassLoader.getSystemResource(name);
2110: }
2111: return cl.getResource(name);
2112: }
2113:
2114: /** protection domain returned when the internal domain is null */
2115: private static java.security.ProtectionDomain allPermDomain;
2116:
2117: /**
2118: * Returns the {@code ProtectionDomain} of this class. If there is a
2119: * security manager installed, this method first calls the security
2120: * manager's {@code checkPermission} method with a
2121: * {@code RuntimePermission("getProtectionDomain")} permission to
2122: * ensure it's ok to get the
2123: * {@code ProtectionDomain}.
2124: *
2125: * @return the ProtectionDomain of this class
2126: *
2127: * @throws SecurityException
2128: * if a security manager exists and its
2129: * {@code checkPermission} method doesn't allow
2130: * getting the ProtectionDomain.
2131: *
2132: * @see java.security.ProtectionDomain
2133: * @see SecurityManager#checkPermission
2134: * @see java.lang.RuntimePermission
2135: * @since 1.2
2136: */
2137: public java.security.ProtectionDomain getProtectionDomain() {
2138: SecurityManager sm = System.getSecurityManager();
2139: if (sm != null) {
2140: sm.checkPermission(SecurityConstants.GET_PD_PERMISSION);
2141: }
2142: java.security.ProtectionDomain pd = getProtectionDomain0();
2143: if (pd == null) {
2144: if (allPermDomain == null) {
2145: java.security.Permissions perms = new java.security.Permissions();
2146: perms.add(SecurityConstants.ALL_PERMISSION);
2147: allPermDomain = new java.security.ProtectionDomain(
2148: null, perms);
2149: }
2150: pd = allPermDomain;
2151: }
2152: return pd;
2153: }
2154:
2155: /**
2156: * Returns the ProtectionDomain of this class.
2157: */
2158: private native java.security.ProtectionDomain getProtectionDomain0();
2159:
2160: /**
2161: * Set the ProtectionDomain for this class. Called by
2162: * ClassLoader.defineClass.
2163: */
2164: native void setProtectionDomain0(java.security.ProtectionDomain pd);
2165:
2166: /*
2167: * Return the Virtual Machine's Class object for the named
2168: * primitive type.
2169: */
2170: static native Class getPrimitiveClass(String name);
2171:
2172: /*
2173: * Check if client is allowed to access members. If access is denied,
2174: * throw a SecurityException.
2175: *
2176: * Be very careful not to change the stack depth of this checkMemberAccess
2177: * call for security reasons.
2178: * See java.lang.SecurityManager.checkMemberAccess.
2179: *
2180: * <p> Default policy: allow all clients access with normal Java access
2181: * control.
2182: */
2183: private void checkMemberAccess(int which, ClassLoader ccl) {
2184: SecurityManager s = System.getSecurityManager();
2185: if (s != null) {
2186: s.checkMemberAccess(this , which);
2187: ClassLoader cl = getClassLoader0();
2188: if ((ccl != null) && (ccl != cl)
2189: && ((cl == null) || !cl.isAncestor(ccl))) {
2190: String name = this .getName();
2191: int i = name.lastIndexOf('.');
2192: if (i != -1) {
2193: s.checkPackageAccess(name.substring(0, i));
2194: }
2195: }
2196: }
2197: }
2198:
2199: /**
2200: * Add a package name prefix if the name is not absolute Remove leading "/"
2201: * if name is absolute
2202: */
2203: private String resolveName(String name) {
2204: if (name == null) {
2205: return name;
2206: }
2207: if (!name.startsWith("/")) {
2208: Class c = this ;
2209: while (c.isArray()) {
2210: c = c.getComponentType();
2211: }
2212: String baseName = c.getName();
2213: int index = baseName.lastIndexOf('.');
2214: if (index != -1) {
2215: name = baseName.substring(0, index).replace('.', '/')
2216: + "/" + name;
2217: }
2218: } else {
2219: name = name.substring(1);
2220: }
2221: return name;
2222: }
2223:
2224: /**
2225: * Reflection support.
2226: */
2227:
2228: // Caches for certain reflective results
2229: private static boolean useCaches = true;
2230: private volatile transient SoftReference declaredFields;
2231: private volatile transient SoftReference publicFields;
2232: private volatile transient SoftReference declaredMethods;
2233: private volatile transient SoftReference publicMethods;
2234: private volatile transient SoftReference declaredConstructors;
2235: private volatile transient SoftReference publicConstructors;
2236: // Intermediate results for getFields and getMethods
2237: private volatile transient SoftReference declaredPublicFields;
2238: private volatile transient SoftReference declaredPublicMethods;
2239:
2240: // Incremented by the VM on each call to JVM TI RedefineClasses()
2241: // that redefines this class or a superclass.
2242: private volatile transient int classRedefinedCount = 0;
2243:
2244: // Value of classRedefinedCount when we last cleared the cached values
2245: // that are sensitive to class redefinition.
2246: private volatile transient int lastRedefinedCount = 0;
2247:
2248: // Clears cached values that might possibly have been obsoleted by
2249: // a class redefinition.
2250: private void clearCachesOnClassRedefinition() {
2251: if (lastRedefinedCount != classRedefinedCount) {
2252: declaredFields = publicFields = declaredPublicFields = null;
2253: declaredMethods = publicMethods = declaredPublicMethods = null;
2254: declaredConstructors = publicConstructors = null;
2255: annotations = declaredAnnotations = null;
2256:
2257: // Use of "volatile" (and synchronization by caller in the case
2258: // of annotations) ensures that no thread sees the update to
2259: // lastRedefinedCount before seeing the caches cleared.
2260: // We do not guard against brief windows during which multiple
2261: // threads might redundantly work to fill an empty cache.
2262: lastRedefinedCount = classRedefinedCount;
2263: }
2264: }
2265:
2266: // Generic signature handling
2267: private native String getGenericSignature();
2268:
2269: // Generic info repository; lazily initialized
2270: private transient ClassRepository genericInfo;
2271:
2272: // accessor for factory
2273: private GenericsFactory getFactory() {
2274: // create scope and factory
2275: return CoreReflectionFactory.make(this , ClassScope.make(this ));
2276: }
2277:
2278: // accessor for generic info repository
2279: private ClassRepository getGenericInfo() {
2280: // lazily initialize repository if necessary
2281: if (genericInfo == null) {
2282: // create and cache generic info repository
2283: genericInfo = ClassRepository.make(getGenericSignature(),
2284: getFactory());
2285: }
2286: return genericInfo; //return cached repository
2287: }
2288:
2289: // Annotations handling
2290: private native byte[] getRawAnnotations();
2291:
2292: native ConstantPool getConstantPool();
2293:
2294: //
2295: //
2296: // java.lang.reflect.Field handling
2297: //
2298: //
2299:
2300: // Returns an array of "root" fields. These Field objects must NOT
2301: // be propagated to the outside world, but must instead be copied
2302: // via ReflectionFactory.copyField.
2303: private Field[] privateGetDeclaredFields(boolean publicOnly) {
2304: checkInitted();
2305: Field[] res = null;
2306: if (useCaches) {
2307: clearCachesOnClassRedefinition();
2308: if (publicOnly) {
2309: if (declaredPublicFields != null) {
2310: res = (Field[]) declaredPublicFields.get();
2311: }
2312: } else {
2313: if (declaredFields != null) {
2314: res = (Field[]) declaredFields.get();
2315: }
2316: }
2317: if (res != null)
2318: return res;
2319: }
2320: // No cached value available; request value from VM
2321: res = Reflection.filterFields(this ,
2322: getDeclaredFields0(publicOnly));
2323: if (useCaches) {
2324: if (publicOnly) {
2325: declaredPublicFields = new SoftReference(res);
2326: } else {
2327: declaredFields = new SoftReference(res);
2328: }
2329: }
2330: return res;
2331: }
2332:
2333: // Returns an array of "root" fields. These Field objects must NOT
2334: // be propagated to the outside world, but must instead be copied
2335: // via ReflectionFactory.copyField.
2336: private Field[] privateGetPublicFields(Set traversedInterfaces) {
2337: checkInitted();
2338: Field[] res = null;
2339: if (useCaches) {
2340: clearCachesOnClassRedefinition();
2341: if (publicFields != null) {
2342: res = (Field[]) publicFields.get();
2343: }
2344: if (res != null)
2345: return res;
2346: }
2347:
2348: // No cached value available; compute value recursively.
2349: // Traverse in correct order for getField().
2350: List fields = new ArrayList();
2351: if (traversedInterfaces == null) {
2352: traversedInterfaces = new HashSet();
2353: }
2354:
2355: // Local fields
2356: Field[] tmp = privateGetDeclaredFields(true);
2357: addAll(fields, tmp);
2358:
2359: // Direct superinterfaces, recursively
2360: Class[] interfaces = getInterfaces();
2361: for (int i = 0; i < interfaces.length; i++) {
2362: Class c = interfaces[i];
2363: if (!traversedInterfaces.contains(c)) {
2364: traversedInterfaces.add(c);
2365: addAll(fields, c
2366: .privateGetPublicFields(traversedInterfaces));
2367: }
2368: }
2369:
2370: // Direct superclass, recursively
2371: if (!isInterface()) {
2372: Class c = getSuperclass();
2373: if (c != null) {
2374: addAll(fields, c
2375: .privateGetPublicFields(traversedInterfaces));
2376: }
2377: }
2378:
2379: res = new Field[fields.size()];
2380: fields.toArray(res);
2381: if (useCaches) {
2382: publicFields = new SoftReference(res);
2383: }
2384: return res;
2385: }
2386:
2387: private static void addAll(Collection c, Field[] o) {
2388: for (int i = 0; i < o.length; i++) {
2389: c.add(o[i]);
2390: }
2391: }
2392:
2393: //
2394: //
2395: // java.lang.reflect.Constructor handling
2396: //
2397: //
2398:
2399: // Returns an array of "root" constructors. These Constructor
2400: // objects must NOT be propagated to the outside world, but must
2401: // instead be copied via ReflectionFactory.copyConstructor.
2402: private Constructor[] privateGetDeclaredConstructors(
2403: boolean publicOnly) {
2404: checkInitted();
2405: Constructor[] res = null;
2406: if (useCaches) {
2407: clearCachesOnClassRedefinition();
2408: if (publicOnly) {
2409: if (publicConstructors != null) {
2410: res = (Constructor[]) publicConstructors.get();
2411: }
2412: } else {
2413: if (declaredConstructors != null) {
2414: res = (Constructor[]) declaredConstructors.get();
2415: }
2416: }
2417: if (res != null)
2418: return res;
2419: }
2420: // No cached value available; request value from VM
2421: if (isInterface()) {
2422: res = new Constructor[0];
2423: } else {
2424: res = getDeclaredConstructors0(publicOnly);
2425: }
2426: if (useCaches) {
2427: if (publicOnly) {
2428: publicConstructors = new SoftReference(res);
2429: } else {
2430: declaredConstructors = new SoftReference(res);
2431: }
2432: }
2433: return res;
2434: }
2435:
2436: //
2437: //
2438: // java.lang.reflect.Method handling
2439: //
2440: //
2441:
2442: // Returns an array of "root" methods. These Method objects must NOT
2443: // be propagated to the outside world, but must instead be copied
2444: // via ReflectionFactory.copyMethod.
2445: private Method[] privateGetDeclaredMethods(boolean publicOnly) {
2446: checkInitted();
2447: Method[] res = null;
2448: if (useCaches) {
2449: clearCachesOnClassRedefinition();
2450: if (publicOnly) {
2451: if (declaredPublicMethods != null) {
2452: res = (Method[]) declaredPublicMethods.get();
2453: }
2454: } else {
2455: if (declaredMethods != null) {
2456: res = (Method[]) declaredMethods.get();
2457: }
2458: }
2459: if (res != null)
2460: return res;
2461: }
2462: // No cached value available; request value from VM
2463: res = Reflection.filterMethods(this ,
2464: getDeclaredMethods0(publicOnly));
2465: if (useCaches) {
2466: if (publicOnly) {
2467: declaredPublicMethods = new SoftReference(res);
2468: } else {
2469: declaredMethods = new SoftReference(res);
2470: }
2471: }
2472: return res;
2473: }
2474:
2475: static class MethodArray {
2476: private Method[] methods;
2477: private int length;
2478:
2479: MethodArray() {
2480: methods = new Method[20];
2481: length = 0;
2482: }
2483:
2484: void add(Method m) {
2485: if (length == methods.length) {
2486: methods = Arrays.copyOf(methods, 2 * methods.length);
2487: }
2488: methods[length++] = m;
2489: }
2490:
2491: void addAll(Method[] ma) {
2492: for (int i = 0; i < ma.length; i++) {
2493: add(ma[i]);
2494: }
2495: }
2496:
2497: void addAll(MethodArray ma) {
2498: for (int i = 0; i < ma.length(); i++) {
2499: add(ma.get(i));
2500: }
2501: }
2502:
2503: void addIfNotPresent(Method newMethod) {
2504: for (int i = 0; i < length; i++) {
2505: Method m = methods[i];
2506: if (m == newMethod
2507: || (m != null && m.equals(newMethod))) {
2508: return;
2509: }
2510: }
2511: add(newMethod);
2512: }
2513:
2514: void addAllIfNotPresent(MethodArray newMethods) {
2515: for (int i = 0; i < newMethods.length(); i++) {
2516: Method m = newMethods.get(i);
2517: if (m != null) {
2518: addIfNotPresent(m);
2519: }
2520: }
2521: }
2522:
2523: int length() {
2524: return length;
2525: }
2526:
2527: Method get(int i) {
2528: return methods[i];
2529: }
2530:
2531: void removeByNameAndSignature(Method toRemove) {
2532: for (int i = 0; i < length; i++) {
2533: Method m = methods[i];
2534: if (m != null
2535: && m.getReturnType() == toRemove
2536: .getReturnType()
2537: && m.getName() == toRemove.getName()
2538: && arrayContentsEq(m.getParameterTypes(),
2539: toRemove.getParameterTypes())) {
2540: methods[i] = null;
2541: }
2542: }
2543: }
2544:
2545: void compactAndTrim() {
2546: int newPos = 0;
2547: // Get rid of null slots
2548: for (int pos = 0; pos < length; pos++) {
2549: Method m = methods[pos];
2550: if (m != null) {
2551: if (pos != newPos) {
2552: methods[newPos] = m;
2553: }
2554: newPos++;
2555: }
2556: }
2557: if (newPos != methods.length) {
2558: methods = Arrays.copyOf(methods, newPos);
2559: }
2560: }
2561:
2562: Method[] getArray() {
2563: return methods;
2564: }
2565: }
2566:
2567: // Returns an array of "root" methods. These Method objects must NOT
2568: // be propagated to the outside world, but must instead be copied
2569: // via ReflectionFactory.copyMethod.
2570: private Method[] privateGetPublicMethods() {
2571: checkInitted();
2572: Method[] res = null;
2573: if (useCaches) {
2574: clearCachesOnClassRedefinition();
2575: if (publicMethods != null) {
2576: res = (Method[]) publicMethods.get();
2577: }
2578: if (res != null)
2579: return res;
2580: }
2581:
2582: // No cached value available; compute value recursively.
2583: // Start by fetching public declared methods
2584: MethodArray methods = new MethodArray();
2585: {
2586: Method[] tmp = privateGetDeclaredMethods(true);
2587: methods.addAll(tmp);
2588: }
2589: // Now recur over superclass and direct superinterfaces.
2590: // Go over superinterfaces first so we can more easily filter
2591: // out concrete implementations inherited from superclasses at
2592: // the end.
2593: MethodArray inheritedMethods = new MethodArray();
2594: Class[] interfaces = getInterfaces();
2595: for (int i = 0; i < interfaces.length; i++) {
2596: inheritedMethods.addAll(interfaces[i]
2597: .privateGetPublicMethods());
2598: }
2599: if (!isInterface()) {
2600: Class c = getSuperclass();
2601: if (c != null) {
2602: MethodArray super s = new MethodArray();
2603: super s.addAll(c.privateGetPublicMethods());
2604: // Filter out concrete implementations of any
2605: // interface methods
2606: for (int i = 0; i < super s.length(); i++) {
2607: Method m = super s.get(i);
2608: if (m != null
2609: && !Modifier.isAbstract(m.getModifiers())) {
2610: inheritedMethods.removeByNameAndSignature(m);
2611: }
2612: }
2613: // Insert superclass's inherited methods before
2614: // superinterfaces' to satisfy getMethod's search
2615: // order
2616: super s.addAll(inheritedMethods);
2617: inheritedMethods = super s;
2618: }
2619: }
2620: // Filter out all local methods from inherited ones
2621: for (int i = 0; i < methods.length(); i++) {
2622: Method m = methods.get(i);
2623: inheritedMethods.removeByNameAndSignature(m);
2624: }
2625: methods.addAllIfNotPresent(inheritedMethods);
2626: methods.compactAndTrim();
2627: res = methods.getArray();
2628: if (useCaches) {
2629: publicMethods = new SoftReference(res);
2630: }
2631: return res;
2632: }
2633:
2634: //
2635: // Helpers for fetchers of one field, method, or constructor
2636: //
2637:
2638: private Field searchFields(Field[] fields, String name) {
2639: String internedName = name.intern();
2640: for (int i = 0; i < fields.length; i++) {
2641: if (fields[i].getName() == internedName) {
2642: return getReflectionFactory().copyField(fields[i]);
2643: }
2644: }
2645: return null;
2646: }
2647:
2648: private Field getField0(String name) throws NoSuchFieldException {
2649: // Note: the intent is that the search algorithm this routine
2650: // uses be equivalent to the ordering imposed by
2651: // privateGetPublicFields(). It fetches only the declared
2652: // public fields for each class, however, to reduce the number
2653: // of Field objects which have to be created for the common
2654: // case where the field being requested is declared in the
2655: // class which is being queried.
2656: Field res = null;
2657: // Search declared public fields
2658: if ((res = searchFields(privateGetDeclaredFields(true), name)) != null) {
2659: return res;
2660: }
2661: // Direct superinterfaces, recursively
2662: Class[] interfaces = getInterfaces();
2663: for (int i = 0; i < interfaces.length; i++) {
2664: Class c = interfaces[i];
2665: if ((res = c.getField0(name)) != null) {
2666: return res;
2667: }
2668: }
2669: // Direct superclass, recursively
2670: if (!isInterface()) {
2671: Class c = getSuperclass();
2672: if (c != null) {
2673: if ((res = c.getField0(name)) != null) {
2674: return res;
2675: }
2676: }
2677: }
2678: return null;
2679: }
2680:
2681: private static Method searchMethods(Method[] methods, String name,
2682: Class[] parameterTypes) {
2683: Method res = null;
2684: String internedName = name.intern();
2685: for (int i = 0; i < methods.length; i++) {
2686: Method m = methods[i];
2687: if (m.getName() == internedName
2688: && arrayContentsEq(parameterTypes, m
2689: .getParameterTypes())
2690: && (res == null || res.getReturnType()
2691: .isAssignableFrom(m.getReturnType())))
2692: res = m;
2693: }
2694:
2695: return (res == null ? res : getReflectionFactory().copyMethod(
2696: res));
2697: }
2698:
2699: private Method getMethod0(String name, Class[] parameterTypes) {
2700: // Note: the intent is that the search algorithm this routine
2701: // uses be equivalent to the ordering imposed by
2702: // privateGetPublicMethods(). It fetches only the declared
2703: // public methods for each class, however, to reduce the
2704: // number of Method objects which have to be created for the
2705: // common case where the method being requested is declared in
2706: // the class which is being queried.
2707: Method res = null;
2708: // Search declared public methods
2709: if ((res = searchMethods(privateGetDeclaredMethods(true), name,
2710: parameterTypes)) != null) {
2711: return res;
2712: }
2713: // Search superclass's methods
2714: if (!isInterface()) {
2715: Class c = getSuperclass();
2716: if (c != null) {
2717: if ((res = c.getMethod0(name, parameterTypes)) != null) {
2718: return res;
2719: }
2720: }
2721: }
2722: // Search superinterfaces' methods
2723: Class[] interfaces = getInterfaces();
2724: for (int i = 0; i < interfaces.length; i++) {
2725: Class c = interfaces[i];
2726: if ((res = c.getMethod0(name, parameterTypes)) != null) {
2727: return res;
2728: }
2729: }
2730: // Not found
2731: return null;
2732: }
2733:
2734: private Constructor<T> getConstructor0(Class[] parameterTypes,
2735: int which) throws NoSuchMethodException {
2736: Constructor[] constructors = privateGetDeclaredConstructors((which == Member.PUBLIC));
2737: for (int i = 0; i < constructors.length; i++) {
2738: if (arrayContentsEq(parameterTypes, constructors[i]
2739: .getParameterTypes())) {
2740: return getReflectionFactory().copyConstructor(
2741: constructors[i]);
2742: }
2743: }
2744: throw new NoSuchMethodException(getName() + ".<init>"
2745: + argumentTypesToString(parameterTypes));
2746: }
2747:
2748: //
2749: // Other helpers and base implementation
2750: //
2751:
2752: private static boolean arrayContentsEq(Object[] a1, Object[] a2) {
2753: if (a1 == null) {
2754: return a2 == null || a2.length == 0;
2755: }
2756:
2757: if (a2 == null) {
2758: return a1.length == 0;
2759: }
2760:
2761: if (a1.length != a2.length) {
2762: return false;
2763: }
2764:
2765: for (int i = 0; i < a1.length; i++) {
2766: if (a1[i] != a2[i]) {
2767: return false;
2768: }
2769: }
2770:
2771: return true;
2772: }
2773:
2774: private static Field[] copyFields(Field[] arg) {
2775: Field[] out = new Field[arg.length];
2776: ReflectionFactory fact = getReflectionFactory();
2777: for (int i = 0; i < arg.length; i++) {
2778: out[i] = fact.copyField(arg[i]);
2779: }
2780: return out;
2781: }
2782:
2783: private static Method[] copyMethods(Method[] arg) {
2784: Method[] out = new Method[arg.length];
2785: ReflectionFactory fact = getReflectionFactory();
2786: for (int i = 0; i < arg.length; i++) {
2787: out[i] = fact.copyMethod(arg[i]);
2788: }
2789: return out;
2790: }
2791:
2792: private static Constructor[] copyConstructors(Constructor[] arg) {
2793: Constructor[] out = new Constructor[arg.length];
2794: ReflectionFactory fact = getReflectionFactory();
2795: for (int i = 0; i < arg.length; i++) {
2796: out[i] = fact.copyConstructor(arg[i]);
2797: }
2798: return out;
2799: }
2800:
2801: private native Field[] getDeclaredFields0(boolean publicOnly);
2802:
2803: private native Method[] getDeclaredMethods0(boolean publicOnly);
2804:
2805: private native Constructor[] getDeclaredConstructors0(
2806: boolean publicOnly);
2807:
2808: private native Class[] getDeclaredClasses0();
2809:
2810: private static String argumentTypesToString(Class[] argTypes) {
2811: StringBuilder buf = new StringBuilder();
2812: buf.append("(");
2813: if (argTypes != null) {
2814: for (int i = 0; i < argTypes.length; i++) {
2815: if (i > 0) {
2816: buf.append(", ");
2817: }
2818: Class c = argTypes[i];
2819: buf.append((c == null) ? "null" : c.getName());
2820: }
2821: }
2822: buf.append(")");
2823: return buf.toString();
2824: }
2825:
2826: /** use serialVersionUID from JDK 1.1 for interoperability */
2827: private static final long serialVersionUID = 3206093459760846163L;
2828:
2829: /**
2830: * Class Class is special cased within the Serialization Stream Protocol.
2831: *
2832: * A Class instance is written initially into an ObjectOutputStream in the
2833: * following format:
2834: * <pre>
2835: * {@code TC_CLASS} ClassDescriptor
2836: * A ClassDescriptor is a special cased serialization of
2837: * a {@code java.io.ObjectStreamClass} instance.
2838: * </pre>
2839: * A new handle is generated for the initial time the class descriptor
2840: * is written into the stream. Future references to the class descriptor
2841: * are written as references to the initial class descriptor instance.
2842: *
2843: * @see java.io.ObjectStreamClass
2844: */
2845: private static final ObjectStreamField[] serialPersistentFields = new ObjectStreamField[0];
2846:
2847: /**
2848: * Returns the assertion status that would be assigned to this
2849: * class if it were to be initialized at the time this method is invoked.
2850: * If this class has had its assertion status set, the most recent
2851: * setting will be returned; otherwise, if any package default assertion
2852: * status pertains to this class, the most recent setting for the most
2853: * specific pertinent package default assertion status is returned;
2854: * otherwise, if this class is not a system class (i.e., it has a
2855: * class loader) its class loader's default assertion status is returned;
2856: * otherwise, the system class default assertion status is returned.
2857: * <p>
2858: * Few programmers will have any need for this method; it is provided
2859: * for the benefit of the JRE itself. (It allows a class to determine at
2860: * the time that it is initialized whether assertions should be enabled.)
2861: * Note that this method is not guaranteed to return the actual
2862: * assertion status that was (or will be) associated with the specified
2863: * class when it was (or will be) initialized.
2864: *
2865: * @return the desired assertion status of the specified class.
2866: * @see java.lang.ClassLoader#setClassAssertionStatus
2867: * @see java.lang.ClassLoader#setPackageAssertionStatus
2868: * @see java.lang.ClassLoader#setDefaultAssertionStatus
2869: * @since 1.4
2870: */
2871: public boolean desiredAssertionStatus() {
2872: ClassLoader loader = getClassLoader();
2873: // If the loader is null this is a system class, so ask the VM
2874: if (loader == null)
2875: return desiredAssertionStatus0(this );
2876:
2877: synchronized (loader) {
2878: // If the classloader has been initialized with
2879: // the assertion directives, ask it. Otherwise,
2880: // ask the VM.
2881: return (loader.classAssertionStatus == null ? desiredAssertionStatus0(this )
2882: : loader.desiredAssertionStatus(getName()));
2883: }
2884: }
2885:
2886: // Retrieves the desired assertion status of this class from the VM
2887: private static native boolean desiredAssertionStatus0(Class clazz);
2888:
2889: /**
2890: * Returns true if and only if this class was declared as an enum in the
2891: * source code.
2892: *
2893: * @return true if and only if this class was declared as an enum in the
2894: * source code
2895: * @since 1.5
2896: */
2897: public boolean isEnum() {
2898: // An enum must both directly extend java.lang.Enum and have
2899: // the ENUM bit set; classes for specialized enum constants
2900: // don't do the former.
2901: return (this .getModifiers() & ENUM) != 0
2902: && this .getSuperclass() == java.lang.Enum.class;
2903: }
2904:
2905: // Fetches the factory for reflective objects
2906: private static ReflectionFactory getReflectionFactory() {
2907: if (reflectionFactory == null) {
2908: reflectionFactory = (ReflectionFactory) java.security.AccessController
2909: .doPrivileged(new sun.reflect.ReflectionFactory.GetReflectionFactoryAction());
2910: }
2911: return reflectionFactory;
2912: }
2913:
2914: private static ReflectionFactory reflectionFactory;
2915:
2916: // To be able to query system properties as soon as they're available
2917: private static boolean initted = false;
2918:
2919: private static void checkInitted() {
2920: if (initted)
2921: return;
2922: AccessController.doPrivileged(new PrivilegedAction() {
2923: public Object run() {
2924: // Tests to ensure the system properties table is fully
2925: // initialized. This is needed because reflection code is
2926: // called very early in the initialization process (before
2927: // command-line arguments have been parsed and therefore
2928: // these user-settable properties installed.) We assume that
2929: // if System.out is non-null then the System class has been
2930: // fully initialized and that the bulk of the startup code
2931: // has been run.
2932:
2933: if (System.out == null) {
2934: // java.lang.System not yet fully initialized
2935: return null;
2936: }
2937:
2938: String val = System.getProperty("sun.reflect.noCaches");
2939: if (val != null && val.equals("true")) {
2940: useCaches = false;
2941: }
2942:
2943: initted = true;
2944: return null;
2945: }
2946: });
2947: }
2948:
2949: /**
2950: * Returns the elements of this enum class or null if this
2951: * Class object does not represent an enum type.
2952: *
2953: * @return an array containing the values comprising the enum class
2954: * represented by this Class object in the order they're
2955: * declared, or null if this Class object does not
2956: * represent an enum type
2957: * @since 1.5
2958: */
2959: public T[] getEnumConstants() {
2960: T[] values = getEnumConstantsShared();
2961: return (values != null) ? values.clone() : null;
2962: }
2963:
2964: /**
2965: * Returns the elements of this enum class or null if this
2966: * Class object does not represent an enum type;
2967: * identical to getEnumConstantsShared except that
2968: * the result is uncloned, cached, and shared by all callers.
2969: */
2970: T[] getEnumConstantsShared() {
2971: if (enumConstants == null) {
2972: if (!isEnum())
2973: return null;
2974: try {
2975: final Method values = getMethod("values");
2976: java.security.AccessController
2977: .doPrivileged(new java.security.PrivilegedAction() {
2978: public Object run() {
2979: values.setAccessible(true);
2980: return null;
2981: }
2982: });
2983: enumConstants = (T[]) values.invoke(null);
2984: }
2985: // These can happen when users concoct enum-like classes
2986: // that don't comply with the enum spec.
2987: catch (InvocationTargetException ex) {
2988: return null;
2989: } catch (NoSuchMethodException ex) {
2990: return null;
2991: } catch (IllegalAccessException ex) {
2992: return null;
2993: }
2994: }
2995: return enumConstants;
2996: }
2997:
2998: private volatile transient T[] enumConstants = null;
2999:
3000: /**
3001: * Returns a map from simple name to enum constant. This package-private
3002: * method is used internally by Enum to implement
3003: * public static <T extends Enum<T>> T valueOf(Class<T>, String)
3004: * efficiently. Note that the map is returned by this method is
3005: * created lazily on first use. Typically it won't ever get created.
3006: */
3007: Map<String, T> enumConstantDirectory() {
3008: if (enumConstantDirectory == null) {
3009: T[] universe = getEnumConstantsShared();
3010: if (universe == null)
3011: throw new IllegalArgumentException(getName()
3012: + " is not an enum type");
3013: Map<String, T> m = new HashMap<String, T>(
3014: 2 * universe.length);
3015: for (T constant : universe)
3016: m.put(((Enum) constant).name(), constant);
3017: enumConstantDirectory = m;
3018: }
3019: return enumConstantDirectory;
3020: }
3021:
3022: private volatile transient Map<String, T> enumConstantDirectory = null;
3023:
3024: /**
3025: * Casts an object to the class or interface represented
3026: * by this {@code Class} object.
3027: *
3028: * @param obj the object to be cast
3029: * @return the object after casting, or null if obj is null
3030: *
3031: * @throws ClassCastException if the object is not
3032: * null and is not assignable to the type T.
3033: *
3034: * @since 1.5
3035: */
3036: public T cast(Object obj) {
3037: if (obj != null && !isInstance(obj))
3038: throw new ClassCastException(cannotCastMsg(obj));
3039: return (T) obj;
3040: }
3041:
3042: private String cannotCastMsg(Object obj) {
3043: return "Cannot cast " + obj.getClass().getName() + " to "
3044: + getName();
3045: }
3046:
3047: /**
3048: * Casts this {@code Class} object to represent a subclass of the class
3049: * represented by the specified class object. Checks that that the cast
3050: * is valid, and throws a {@code ClassCastException} if it is not. If
3051: * this method succeeds, it always returns a reference to this class object.
3052: *
3053: * <p>This method is useful when a client needs to "narrow" the type of
3054: * a {@code Class} object to pass it to an API that restricts the
3055: * {@code Class} objects that it is willing to accept. A cast would
3056: * generate a compile-time warning, as the correctness of the cast
3057: * could not be checked at runtime (because generic types are implemented
3058: * by erasure).
3059: *
3060: * @return this {@code Class} object, cast to represent a subclass of
3061: * the specified class object.
3062: * @throws ClassCastException if this {@code Class} object does not
3063: * represent a subclass of the specified class (here "subclass" includes
3064: * the class itself).
3065: * @since 1.5
3066: */
3067: public <U> Class<? extends U> asSubclass(Class<U> clazz) {
3068: if (clazz.isAssignableFrom(this ))
3069: return (Class<? extends U>) this ;
3070: else
3071: throw new ClassCastException(this .toString());
3072: }
3073:
3074: /**
3075: * @throws NullPointerException {@inheritDoc}
3076: * @since 1.5
3077: */
3078: public <A extends Annotation> A getAnnotation(
3079: Class<A> annotationClass) {
3080: if (annotationClass == null)
3081: throw new NullPointerException();
3082:
3083: initAnnotationsIfNecessary();
3084: return (A) annotations.get(annotationClass);
3085: }
3086:
3087: /**
3088: * @throws NullPointerException {@inheritDoc}
3089: * @since 1.5
3090: */
3091: public boolean isAnnotationPresent(
3092: Class<? extends Annotation> annotationClass) {
3093: if (annotationClass == null)
3094: throw new NullPointerException();
3095:
3096: return getAnnotation(annotationClass) != null;
3097: }
3098:
3099: private static Annotation[] EMPTY_ANNOTATIONS_ARRAY = new Annotation[0];
3100:
3101: /**
3102: * @since 1.5
3103: */
3104: public Annotation[] getAnnotations() {
3105: initAnnotationsIfNecessary();
3106: return annotations.values().toArray(EMPTY_ANNOTATIONS_ARRAY);
3107: }
3108:
3109: /**
3110: * @since 1.5
3111: */
3112: public Annotation[] getDeclaredAnnotations() {
3113: initAnnotationsIfNecessary();
3114: return declaredAnnotations.values().toArray(
3115: EMPTY_ANNOTATIONS_ARRAY);
3116: }
3117:
3118: // Annotations cache
3119: private transient Map<Class, Annotation> annotations;
3120: private transient Map<Class, Annotation> declaredAnnotations;
3121:
3122: private synchronized void initAnnotationsIfNecessary() {
3123: clearCachesOnClassRedefinition();
3124: if (annotations != null)
3125: return;
3126: declaredAnnotations = AnnotationParser.parseAnnotations(
3127: getRawAnnotations(), getConstantPool(), this );
3128: Class<?> super Class = getSuperclass();
3129: if (super Class == null) {
3130: annotations = declaredAnnotations;
3131: } else {
3132: annotations = new HashMap<Class, Annotation>();
3133: super Class.initAnnotationsIfNecessary();
3134: for (Map.Entry<Class, Annotation> e : super Class.annotations
3135: .entrySet()) {
3136: Class annotationClass = e.getKey();
3137: if (AnnotationType.getInstance(annotationClass)
3138: .isInherited())
3139: annotations.put(annotationClass, e.getValue());
3140: }
3141: annotations.putAll(declaredAnnotations);
3142: }
3143: }
3144:
3145: // Annotation types cache their internal (AnnotationType) form
3146:
3147: private AnnotationType annotationType;
3148:
3149: void setAnnotationType(AnnotationType type) {
3150: annotationType = type;
3151: }
3152:
3153: AnnotationType getAnnotationType() {
3154: return annotationType;
3155: }
3156: }
|