/src/share/classes/java/lang/Class.java
Java | 3126 lines | 1118 code | 236 blank | 1772 comment | 337 complexity | 20ef9ef5e0e17d13786fa1abfba38261 MD5 | raw file
Possible License(s): BSD-3-Clause-No-Nuclear-License-2014, LGPL-3.0, GPL-2.0
Large files files are truncated, but you can click here to view the full file
- /*
- * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
- package java.lang;
- import java.lang.reflect.Array;
- import java.lang.reflect.GenericArrayType;
- import java.lang.reflect.Member;
- import java.lang.reflect.Field;
- import java.lang.reflect.Method;
- import java.lang.reflect.Constructor;
- import java.lang.reflect.Modifier;
- import java.lang.reflect.Type;
- import java.lang.reflect.TypeVariable;
- import java.lang.reflect.InvocationTargetException;
- import java.lang.ref.SoftReference;
- import java.io.InputStream;
- import java.io.ObjectStreamField;
- import java.security.AccessController;
- import java.security.PrivilegedAction;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.Collection;
- import java.util.HashSet;
- import java.util.List;
- import java.util.Set;
- import java.util.Map;
- import java.util.HashMap;
- import sun.misc.Unsafe;
- import sun.reflect.ConstantPool;
- import sun.reflect.Reflection;
- import sun.reflect.ReflectionFactory;
- import sun.reflect.generics.factory.CoreReflectionFactory;
- import sun.reflect.generics.factory.GenericsFactory;
- import sun.reflect.generics.repository.ClassRepository;
- import sun.reflect.generics.repository.MethodRepository;
- import sun.reflect.generics.repository.ConstructorRepository;
- import sun.reflect.generics.scope.ClassScope;
- import sun.security.util.SecurityConstants;
- import java.lang.annotation.Annotation;
- import sun.reflect.annotation.*;
- /**
- * Instances of the class {@code Class} represent classes and
- * interfaces in a running Java application. An enum is a kind of
- * class and an annotation is a kind of interface. Every array also
- * belongs to a class that is reflected as a {@code Class} object
- * that is shared by all arrays with the same element type and number
- * of dimensions. The primitive Java types ({@code boolean},
- * {@code byte}, {@code char}, {@code short},
- * {@code int}, {@code long}, {@code float}, and
- * {@code double}), and the keyword {@code void} are also
- * represented as {@code Class} objects.
- *
- * <p> {@code Class} has no public constructor. Instead {@code Class}
- * objects are constructed automatically by the Java Virtual Machine as classes
- * are loaded and by calls to the {@code defineClass} method in the class
- * loader.
- *
- * <p> The following example uses a {@code Class} object to print the
- * class name of an object:
- *
- * <p> <blockquote><pre>
- * void printClassName(Object obj) {
- * System.out.println("The class of " + obj +
- * " is " + obj.getClass().getName());
- * }
- * </pre></blockquote>
- *
- * <p> It is also possible to get the {@code Class} object for a named
- * type (or for void) using a class literal. See Section 15.8.2 of
- * <cite>The Java™ Language Specification</cite>.
- * For example:
- *
- * <p> <blockquote>
- * {@code System.out.println("The name of class Foo is: "+Foo.class.getName());}
- * </blockquote>
- *
- * @param <T> the type of the class modeled by this {@code Class}
- * object. For example, the type of {@code String.class} is {@code
- * Class<String>}. Use {@code Class<?>} if the class being modeled is
- * unknown.
- *
- * @author unascribed
- * @see java.lang.ClassLoader#defineClass(byte[], int, int)
- * @since JDK1.0
- */
- public final
- class Class<T> implements java.io.Serializable,
- java.lang.reflect.GenericDeclaration,
- java.lang.reflect.Type,
- java.lang.reflect.AnnotatedElement {
- private static final int ANNOTATION= 0x00002000;
- private static final int ENUM = 0x00004000;
- private static final int SYNTHETIC = 0x00001000;
- private static native void registerNatives();
- static {
- registerNatives();
- }
- /*
- * Constructor. Only the Java Virtual Machine creates Class
- * objects.
- */
- private Class() {}
- /**
- * Converts the object to a string. The string representation is the
- * string "class" or "interface", followed by a space, and then by the
- * fully qualified name of the class in the format returned by
- * {@code getName}. If this {@code Class} object represents a
- * primitive type, this method returns the name of the primitive type. If
- * this {@code Class} object represents void this method returns
- * "void".
- *
- * @return a string representation of this class object.
- */
- public String toString() {
- return (isInterface() ? "interface " : (isPrimitive() ? "" : "class "))
- + getName();
- }
- /**
- * Returns the {@code Class} object associated with the class or
- * interface with the given string name. Invoking this method is
- * equivalent to:
- *
- * <blockquote>
- * {@code Class.forName(className, true, currentLoader)}
- * </blockquote>
- *
- * where {@code currentLoader} denotes the defining class loader of
- * the current class.
- *
- * <p> For example, the following code fragment returns the
- * runtime {@code Class} descriptor for the class named
- * {@code java.lang.Thread}:
- *
- * <blockquote>
- * {@code Class t = Class.forName("java.lang.Thread")}
- * </blockquote>
- * <p>
- * A call to {@code forName("X")} causes the class named
- * {@code X} to be initialized.
- *
- * @param className the fully qualified name of the desired class.
- * @return the {@code Class} object for the class with the
- * specified name.
- * @exception LinkageError if the linkage fails
- * @exception ExceptionInInitializerError if the initialization provoked
- * by this method fails
- * @exception ClassNotFoundException if the class cannot be located
- */
- public static Class<?> forName(String className)
- throws ClassNotFoundException {
- return forName0(className, true, ClassLoader.getCallerClassLoader());
- }
- /**
- * Returns the {@code Class} object associated with the class or
- * interface with the given string name, using the given class loader.
- * Given the fully qualified name for a class or interface (in the same
- * format returned by {@code getName}) this method attempts to
- * locate, load, and link the class or interface. The specified class
- * loader is used to load the class or interface. If the parameter
- * {@code loader} is null, the class is loaded through the bootstrap
- * class loader. The class is initialized only if the
- * {@code initialize} parameter is {@code true} and if it has
- * not been initialized earlier.
- *
- * <p> If {@code name} denotes a primitive type or void, an attempt
- * will be made to locate a user-defined class in the unnamed package whose
- * name is {@code name}. Therefore, this method cannot be used to
- * obtain any of the {@code Class} objects representing primitive
- * types or void.
- *
- * <p> If {@code name} denotes an array class, the component type of
- * the array class is loaded but not initialized.
- *
- * <p> For example, in an instance method the expression:
- *
- * <blockquote>
- * {@code Class.forName("Foo")}
- * </blockquote>
- *
- * is equivalent to:
- *
- * <blockquote>
- * {@code Class.forName("Foo", true, this.getClass().getClassLoader())}
- * </blockquote>
- *
- * Note that this method throws errors related to loading, linking or
- * initializing as specified in Sections 12.2, 12.3 and 12.4 of <em>The
- * Java Language Specification</em>.
- * Note that this method does not check whether the requested class
- * is accessible to its caller.
- *
- * <p> If the {@code loader} is {@code null}, and a security
- * manager is present, and the caller's class loader is not null, then this
- * method calls the security manager's {@code checkPermission} method
- * with a {@code RuntimePermission("getClassLoader")} permission to
- * ensure it's ok to access the bootstrap class loader.
- *
- * @param name fully qualified name of the desired class
- * @param initialize whether the class must be initialized
- * @param loader class loader from which the class must be loaded
- * @return class object representing the desired class
- *
- * @exception LinkageError if the linkage fails
- * @exception ExceptionInInitializerError if the initialization provoked
- * by this method fails
- * @exception ClassNotFoundException if the class cannot be located by
- * the specified class loader
- *
- * @see java.lang.Class#forName(String)
- * @see java.lang.ClassLoader
- * @since 1.2
- */
- public static Class<?> forName(String name, boolean initialize,
- ClassLoader loader)
- throws ClassNotFoundException
- {
- if (loader == null) {
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- ClassLoader ccl = ClassLoader.getCallerClassLoader();
- if (ccl != null) {
- sm.checkPermission(
- SecurityConstants.GET_CLASSLOADER_PERMISSION);
- }
- }
- }
- return forName0(name, initialize, loader);
- }
- /** Called after security checks have been made. */
- private static native Class<?> forName0(String name, boolean initialize,
- ClassLoader loader)
- throws ClassNotFoundException;
- /**
- * Creates a new instance of the class represented by this {@code Class}
- * object. The class is instantiated as if by a {@code new}
- * expression with an empty argument list. The class is initialized if it
- * has not already been initialized.
- *
- * <p>Note that this method propagates any exception thrown by the
- * nullary constructor, including a checked exception. Use of
- * this method effectively bypasses the compile-time exception
- * checking that would otherwise be performed by the compiler.
- * The {@link
- * java.lang.reflect.Constructor#newInstance(java.lang.Object...)
- * Constructor.newInstance} method avoids this problem by wrapping
- * any exception thrown by the constructor in a (checked) {@link
- * java.lang.reflect.InvocationTargetException}.
- *
- * @return a newly allocated instance of the class represented by this
- * object.
- * @exception IllegalAccessException if the class or its nullary
- * constructor is not accessible.
- * @exception InstantiationException
- * if this {@code Class} represents an abstract class,
- * an interface, an array class, a primitive type, or void;
- * or if the class has no nullary constructor;
- * or if the instantiation fails for some other reason.
- * @exception ExceptionInInitializerError if the initialization
- * provoked by this method fails.
- * @exception SecurityException
- * If a security manager, <i>s</i>, is present and any of the
- * following conditions is met:
- *
- * <ul>
- *
- * <li> invocation of
- * {@link SecurityManager#checkMemberAccess
- * s.checkMemberAccess(this, Member.PUBLIC)} denies
- * creation of new instances of this class
- *
- * <li> the caller's class loader is not the same as or an
- * ancestor of the class loader for the current class and
- * invocation of {@link SecurityManager#checkPackageAccess
- * s.checkPackageAccess()} denies access to the package
- * of this class
- *
- * </ul>
- *
- */
- public T newInstance()
- throws InstantiationException, IllegalAccessException
- {
- if (System.getSecurityManager() != null) {
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
- }
- return newInstance0();
- }
- private T newInstance0()
- throws InstantiationException, IllegalAccessException
- {
- // NOTE: the following code may not be strictly correct under
- // the current Java memory model.
- // Constructor lookup
- if (cachedConstructor == null) {
- if (this == Class.class) {
- throw new IllegalAccessException(
- "Can not call newInstance() on the Class for java.lang.Class"
- );
- }
- try {
- Class<?>[] empty = {};
- final Constructor<T> c = getConstructor0(empty, Member.DECLARED);
- // Disable accessibility checks on the constructor
- // since we have to do the security check here anyway
- // (the stack depth is wrong for the Constructor's
- // security check to work)
- java.security.AccessController.doPrivileged(
- new java.security.PrivilegedAction<Void>() {
- public Void run() {
- c.setAccessible(true);
- return null;
- }
- });
- cachedConstructor = c;
- } catch (NoSuchMethodException e) {
- throw (InstantiationException)
- new InstantiationException(getName()).initCause(e);
- }
- }
- Constructor<T> tmpConstructor = cachedConstructor;
- // Security check (same as in java.lang.reflect.Constructor)
- int modifiers = tmpConstructor.getModifiers();
- if (!Reflection.quickCheckMemberAccess(this, modifiers)) {
- Class<?> caller = Reflection.getCallerClass(3);
- if (newInstanceCallerCache != caller) {
- Reflection.ensureMemberAccess(caller, this, null, modifiers);
- newInstanceCallerCache = caller;
- }
- }
- // Run constructor
- try {
- return tmpConstructor.newInstance((Object[])null);
- } catch (InvocationTargetException e) {
- Unsafe.getUnsafe().throwException(e.getTargetException());
- // Not reached
- return null;
- }
- }
- private volatile transient Constructor<T> cachedConstructor;
- private volatile transient Class<?> newInstanceCallerCache;
- /**
- * Determines if the specified {@code Object} is assignment-compatible
- * with the object represented by this {@code Class}. This method is
- * the dynamic equivalent of the Java language {@code instanceof}
- * operator. The method returns {@code true} if the specified
- * {@code Object} argument is non-null and can be cast to the
- * reference type represented by this {@code Class} object without
- * raising a {@code ClassCastException.} It returns {@code false}
- * otherwise.
- *
- * <p> Specifically, if this {@code Class} object represents a
- * declared class, this method returns {@code true} if the specified
- * {@code Object} argument is an instance of the represented class (or
- * of any of its subclasses); it returns {@code false} otherwise. If
- * this {@code Class} object represents an array class, this method
- * returns {@code true} if the specified {@code Object} argument
- * can be converted to an object of the array class by an identity
- * conversion or by a widening reference conversion; it returns
- * {@code false} otherwise. If this {@code Class} object
- * represents an interface, this method returns {@code true} if the
- * class or any superclass of the specified {@code Object} argument
- * implements this interface; it returns {@code false} otherwise. If
- * this {@code Class} object represents a primitive type, this method
- * returns {@code false}.
- *
- * @param obj the object to check
- * @return true if {@code obj} is an instance of this class
- *
- * @since JDK1.1
- */
- public native boolean isInstance(Object obj);
- /**
- * Determines if the class or interface represented by this
- * {@code Class} object is either the same as, or is a superclass or
- * superinterface of, the class or interface represented by the specified
- * {@code Class} parameter. It returns {@code true} if so;
- * otherwise it returns {@code false}. If this {@code Class}
- * object represents a primitive type, this method returns
- * {@code true} if the specified {@code Class} parameter is
- * exactly this {@code Class} object; otherwise it returns
- * {@code false}.
- *
- * <p> Specifically, this method tests whether the type represented by the
- * specified {@code Class} parameter can be converted to the type
- * represented by this {@code Class} object via an identity conversion
- * or via a widening reference conversion. See <em>The Java Language
- * Specification</em>, sections 5.1.1 and 5.1.4 , for details.
- *
- * @param cls the {@code Class} object to be checked
- * @return the {@code boolean} value indicating whether objects of the
- * type {@code cls} can be assigned to objects of this class
- * @exception NullPointerException if the specified Class parameter is
- * null.
- * @since JDK1.1
- */
- public native boolean isAssignableFrom(Class<?> cls);
- /**
- * Determines if the specified {@code Class} object represents an
- * interface type.
- *
- * @return {@code true} if this object represents an interface;
- * {@code false} otherwise.
- */
- public native boolean isInterface();
- /**
- * Determines if this {@code Class} object represents an array class.
- *
- * @return {@code true} if this object represents an array class;
- * {@code false} otherwise.
- * @since JDK1.1
- */
- public native boolean isArray();
- /**
- * Determines if the specified {@code Class} object represents a
- * primitive type.
- *
- * <p> There are nine predefined {@code Class} objects to represent
- * the eight primitive types and void. These are created by the Java
- * Virtual Machine, and have the same names as the primitive types that
- * they represent, namely {@code boolean}, {@code byte},
- * {@code char}, {@code short}, {@code int},
- * {@code long}, {@code float}, and {@code double}.
- *
- * <p> These objects may only be accessed via the following public static
- * final variables, and are the only {@code Class} objects for which
- * this method returns {@code true}.
- *
- * @return true if and only if this class represents a primitive type
- *
- * @see java.lang.Boolean#TYPE
- * @see java.lang.Character#TYPE
- * @see java.lang.Byte#TYPE
- * @see java.lang.Short#TYPE
- * @see java.lang.Integer#TYPE
- * @see java.lang.Long#TYPE
- * @see java.lang.Float#TYPE
- * @see java.lang.Double#TYPE
- * @see java.lang.Void#TYPE
- * @since JDK1.1
- */
- public native boolean isPrimitive();
- /**
- * Returns true if this {@code Class} object represents an annotation
- * type. Note that if this method returns true, {@link #isInterface()}
- * would also return true, as all annotation types are also interfaces.
- *
- * @return {@code true} if this class object represents an annotation
- * type; {@code false} otherwise
- * @since 1.5
- */
- public boolean isAnnotation() {
- return (getModifiers() & ANNOTATION) != 0;
- }
- /**
- * Returns {@code true} if this class is a synthetic class;
- * returns {@code false} otherwise.
- * @return {@code true} if and only if this class is a synthetic class as
- * defined by the Java Language Specification.
- * @since 1.5
- */
- public boolean isSynthetic() {
- return (getModifiers() & SYNTHETIC) != 0;
- }
- /**
- * Returns the name of the entity (class, interface, array class,
- * primitive type, or void) represented by this {@code Class} object,
- * as a {@code String}.
- *
- * <p> If this class object represents a reference type that is not an
- * array type then the binary name of the class is returned, as specified
- * by
- * <cite>The Java™ Language Specification</cite>.
- *
- * <p> If this class object represents a primitive type or void, then the
- * name returned is a {@code String} equal to the Java language
- * keyword corresponding to the primitive type or void.
- *
- * <p> If this class object represents a class of arrays, then the internal
- * form of the name consists of the name of the element type preceded by
- * one or more '{@code [}' characters representing the depth of the array
- * nesting. The encoding of element type names is as follows:
- *
- * <blockquote><table summary="Element types and encodings">
- * <tr><th> Element Type <th> <th> Encoding
- * <tr><td> boolean <td> <td align=center> Z
- * <tr><td> byte <td> <td align=center> B
- * <tr><td> char <td> <td align=center> C
- * <tr><td> class or interface
- * <td> <td align=center> L<i>classname</i>;
- * <tr><td> double <td> <td align=center> D
- * <tr><td> float <td> <td align=center> F
- * <tr><td> int <td> <td align=center> I
- * <tr><td> long <td> <td align=center> J
- * <tr><td> short <td> <td align=center> S
- * </table></blockquote>
- *
- * <p> The class or interface name <i>classname</i> is the binary name of
- * the class specified above.
- *
- * <p> Examples:
- * <blockquote><pre>
- * String.class.getName()
- * returns "java.lang.String"
- * byte.class.getName()
- * returns "byte"
- * (new Object[3]).getClass().getName()
- * returns "[Ljava.lang.Object;"
- * (new int[3][4][5][6][7][8][9]).getClass().getName()
- * returns "[[[[[[[I"
- * </pre></blockquote>
- *
- * @return the name of the class or interface
- * represented by this object.
- */
- public String getName() {
- String name = this.name;
- if (name == null)
- this.name = name = getName0();
- return name;
- }
- // cache the name to reduce the number of calls into the VM
- private transient String name;
- private native String getName0();
- /**
- * Returns the class loader for the class. Some implementations may use
- * null to represent the bootstrap class loader. This method will return
- * null in such implementations if this class was loaded by the bootstrap
- * class loader.
- *
- * <p> If a security manager is present, and the caller's class loader is
- * not null and the caller's class loader is not the same as or an ancestor of
- * the class loader for the class whose class loader is requested, then
- * this method calls the security manager's {@code checkPermission}
- * method with a {@code RuntimePermission("getClassLoader")}
- * permission to ensure it's ok to access the class loader for the class.
- *
- * <p>If this object
- * represents a primitive type or void, null is returned.
- *
- * @return the class loader that loaded the class or interface
- * represented by this object.
- * @throws SecurityException
- * if a security manager exists and its
- * {@code checkPermission} method denies
- * access to the class loader for the class.
- * @see java.lang.ClassLoader
- * @see SecurityManager#checkPermission
- * @see java.lang.RuntimePermission
- */
- public ClassLoader getClassLoader() {
- ClassLoader cl = getClassLoader0();
- if (cl == null)
- return null;
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- ClassLoader ccl = ClassLoader.getCallerClassLoader();
- if (ccl != null && ccl != cl && !cl.isAncestor(ccl)) {
- sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
- }
- }
- return cl;
- }
- // Package-private to allow ClassLoader access
- native ClassLoader getClassLoader0();
- /**
- * Returns an array of {@code TypeVariable} objects that represent the
- * type variables declared by the generic declaration represented by this
- * {@code GenericDeclaration} object, in declaration order. Returns an
- * array of length 0 if the underlying generic declaration declares no type
- * variables.
- *
- * @return an array of {@code TypeVariable} objects that represent
- * the type variables declared by this generic declaration
- * @throws java.lang.reflect.GenericSignatureFormatError if the generic
- * signature of this generic declaration does not conform to
- * the format specified in
- * <cite>The Java™ Virtual Machine Specification</cite>
- * @since 1.5
- */
- @SuppressWarnings("unchecked")
- public TypeVariable<Class<T>>[] getTypeParameters() {
- if (getGenericSignature() != null)
- return (TypeVariable<Class<T>>[])getGenericInfo().getTypeParameters();
- else
- return (TypeVariable<Class<T>>[])new TypeVariable<?>[0];
- }
- /**
- * Returns the {@code Class} representing the superclass of the entity
- * (class, interface, primitive type or void) represented by this
- * {@code Class}. If this {@code Class} represents either the
- * {@code Object} class, an interface, a primitive type, or void, then
- * null is returned. If this object represents an array class then the
- * {@code Class} object representing the {@code Object} class is
- * returned.
- *
- * @return the superclass of the class represented by this object.
- */
- public native Class<? super T> getSuperclass();
- /**
- * Returns the {@code Type} representing the direct superclass of
- * the entity (class, interface, primitive type or void) represented by
- * this {@code Class}.
- *
- * <p>If the superclass is a parameterized type, the {@code Type}
- * object returned must accurately reflect the actual type
- * parameters used in the source code. The parameterized type
- * representing the superclass is created if it had not been
- * created before. See the declaration of {@link
- * java.lang.reflect.ParameterizedType ParameterizedType} for the
- * semantics of the creation process for parameterized types. If
- * this {@code Class} represents either the {@code Object}
- * class, an interface, a primitive type, or void, then null is
- * returned. If this object represents an array class then the
- * {@code Class} object representing the {@code Object} class is
- * returned.
- *
- * @throws java.lang.reflect.GenericSignatureFormatError if the generic
- * class signature does not conform to the format specified in
- * <cite>The Java™ Virtual Machine Specification</cite>
- * @throws TypeNotPresentException if the generic superclass
- * refers to a non-existent type declaration
- * @throws java.lang.reflect.MalformedParameterizedTypeException if the
- * generic superclass refers to a parameterized type that cannot be
- * instantiated for any reason
- * @return the superclass of the class represented by this object
- * @since 1.5
- */
- public Type getGenericSuperclass() {
- if (getGenericSignature() != null) {
- // Historical irregularity:
- // Generic signature marks interfaces with superclass = Object
- // but this API returns null for interfaces
- if (isInterface())
- return null;
- return getGenericInfo().getSuperclass();
- } else
- return getSuperclass();
- }
- /**
- * Gets the package for this class. The class loader of this class is used
- * to find the package. If the class was loaded by the bootstrap class
- * loader the set of packages loaded from CLASSPATH is searched to find the
- * package of the class. Null is returned if no package object was created
- * by the class loader of this class.
- *
- * <p> Packages have attributes for versions and specifications only if the
- * information was defined in the manifests that accompany the classes, and
- * if the class loader created the package instance with the attributes
- * from the manifest.
- *
- * @return the package of the class, or null if no package
- * information is available from the archive or codebase.
- */
- public Package getPackage() {
- return Package.getPackage(this);
- }
- /**
- * Determines the interfaces implemented by the class or interface
- * represented by this object.
- *
- * <p> If this object represents a class, the return value is an array
- * containing objects representing all interfaces implemented by the
- * class. The order of the interface objects in the array corresponds to
- * the order of the interface names in the {@code implements} clause
- * of the declaration of the class represented by this object. For
- * example, given the declaration:
- * <blockquote>
- * {@code class Shimmer implements FloorWax, DessertTopping { ... }}
- * </blockquote>
- * suppose the value of {@code s} is an instance of
- * {@code Shimmer}; the value of the expression:
- * <blockquote>
- * {@code s.getClass().getInterfaces()[0]}
- * </blockquote>
- * is the {@code Class} object that represents interface
- * {@code FloorWax}; and the value of:
- * <blockquote>
- * {@code s.getClass().getInterfaces()[1]}
- * </blockquote>
- * is the {@code Class} object that represents interface
- * {@code DessertTopping}.
- *
- * <p> If this object represents an interface, the array contains objects
- * representing all interfaces extended by the interface. The order of the
- * interface objects in the array corresponds to the order of the interface
- * names in the {@code extends} clause of the declaration of the
- * interface represented by this object.
- *
- * <p> If this object represents a class or interface that implements no
- * interfaces, the method returns an array of length 0.
- *
- * <p> If this object represents a primitive type or void, the method
- * returns an array of length 0.
- *
- * @return an array of interfaces implemented by this class.
- */
- public native Class<?>[] getInterfaces();
- /**
- * Returns the {@code Type}s representing the interfaces
- * directly implemented by the class or interface represented by
- * this object.
- *
- * <p>If a superinterface is a parameterized type, the
- * {@code Type} object returned for it must accurately reflect
- * the actual type parameters used in the source code. The
- * parameterized type representing each superinterface is created
- * if it had not been created before. See the declaration of
- * {@link java.lang.reflect.ParameterizedType ParameterizedType}
- * for the semantics of the creation process for parameterized
- * types.
- *
- * <p> If this object represents a class, the return value is an
- * array containing objects representing all interfaces
- * implemented by the class. The order of the interface objects in
- * the array corresponds to the order of the interface names in
- * the {@code implements} clause of the declaration of the class
- * represented by this object. In the case of an array class, the
- * interfaces {@code Cloneable} and {@code Serializable} are
- * returned in that order.
- *
- * <p>If this object represents an interface, the array contains
- * objects representing all interfaces directly extended by the
- * interface. The order of the interface objects in the array
- * corresponds to the order of the interface names in the
- * {@code extends} clause of the declaration of the interface
- * represented by this object.
- *
- * <p>If this object represents a class or interface that
- * implements no interfaces, the method returns an array of length
- * 0.
- *
- * <p>If this object represents a primitive type or void, the
- * method returns an array of length 0.
- *
- * @throws java.lang.reflect.GenericSignatureFormatError
- * if the generic class signature does not conform to the format
- * specified in
- * <cite>The Java™ Virtual Machine Specification</cite>
- * @throws TypeNotPresentException if any of the generic
- * superinterfaces refers to a non-existent type declaration
- * @throws java.lang.reflect.MalformedParameterizedTypeException
- * if any of the generic superinterfaces refer to a parameterized
- * type that cannot be instantiated for any reason
- * @return an array of interfaces implemented by this class
- * @since 1.5
- */
- public Type[] getGenericInterfaces() {
- if (getGenericSignature() != null)
- return getGenericInfo().getSuperInterfaces();
- else
- return getInterfaces();
- }
- /**
- * Returns the {@code Class} representing the component type of an
- * array. If this class does not represent an array class this method
- * returns null.
- *
- * @return the {@code Class} representing the component type of this
- * class if this class is an array
- * @see java.lang.reflect.Array
- * @since JDK1.1
- */
- public native Class<?> getComponentType();
- /**
- * Returns the Java language modifiers for this class or interface, encoded
- * in an integer. The modifiers consist of the Java Virtual Machine's
- * constants for {@code public}, {@code protected},
- * {@code private}, {@code final}, {@code static},
- * {@code abstract} and {@code interface}; they should be decoded
- * using the methods of class {@code Modifier}.
- *
- * <p> If the underlying class is an array class, then its
- * {@code public}, {@code private} and {@code protected}
- * modifiers are the same as those of its component type. If this
- * {@code Class} represents a primitive type or void, its
- * {@code public} modifier is always {@code true}, and its
- * {@code protected} and {@code private} modifiers are always
- * {@code false}. If this object represents an array class, a
- * primitive type or void, then its {@code final} modifier is always
- * {@code true} and its interface modifier is always
- * {@code false}. The values of its other modifiers are not determined
- * by this specification.
- *
- * <p> The modifier encodings are defined in <em>The Java Virtual Machine
- * Specification</em>, table 4.1.
- *
- * @return the {@code int} representing the modifiers for this class
- * @see java.lang.reflect.Modifier
- * @since JDK1.1
- */
- public native int getModifiers();
- /**
- * Gets the signers of this class.
- *
- * @return the signers of this class, or null if there are no signers. In
- * particular, this method returns null if this object represents
- * a primitive type or void.
- * @since JDK1.1
- */
- public native Object[] getSigners();
- /**
- * Set the signers of this class.
- */
- native void setSigners(Object[] signers);
- /**
- * If this {@code Class} object represents a local or anonymous
- * class within a method, returns a {@link
- * java.lang.reflect.Method Method} object representing the
- * immediately enclosing method of the underlying class. Returns
- * {@code null} otherwise.
- *
- * In particular, this method returns {@code null} if the underlying
- * class is a local or anonymous class immediately enclosed by a type
- * declaration, instance initializer or static initializer.
- *
- * @return the immediately enclosing method of the underlying class, if
- * that class is a local or anonymous class; otherwise {@code null}.
- * @since 1.5
- */
- public Method getEnclosingMethod() {
- EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
- if (enclosingInfo == null)
- return null;
- else {
- if (!enclosingInfo.isMethod())
- return null;
- MethodRepository typeInfo = MethodRepository.make(enclosingInfo.getDescriptor(),
- getFactory());
- Class<?> returnType = toClass(typeInfo.getReturnType());
- Type [] parameterTypes = typeInfo.getParameterTypes();
- Class<?>[] parameterClasses = new Class<?>[parameterTypes.length];
- // Convert Types to Classes; returned types *should*
- // be class objects since the methodDescriptor's used
- // don't have generics information
- for(int i = 0; i < parameterClasses.length; i++)
- parameterClasses[i] = toClass(parameterTypes[i]);
- /*
- * Loop over all declared methods; match method name,
- * number of and type of parameters, *and* return
- * type. Matching return type is also necessary
- * because of covariant returns, etc.
- */
- for(Method m: enclosingInfo.getEnclosingClass().getDeclaredMethods()) {
- if (m.getName().equals(enclosingInfo.getName()) ) {
- Class<?>[] candidateParamClasses = m.getParameterTypes();
- if (candidateParamClasses.length == parameterClasses.length) {
- boolean matches = true;
- for(int i = 0; i < candidateParamClasses.length; i++) {
- if (!candidateParamClasses[i].equals(parameterClasses[i])) {
- matches = false;
- break;
- }
- }
- if (matches) { // finally, check return type
- if (m.getReturnType().equals(returnType) )
- return m;
- }
- }
- }
- }
- throw new InternalError("Enclosing method not found");
- }
- }
- private native Object[] getEnclosingMethod0();
- private EnclosingMethodInfo getEnclosingMethodInfo() {
- Object[] enclosingInfo = getEnclosingMethod0();
- if (enclosingInfo == null)
- return null;
- else {
- return new EnclosingMethodInfo(enclosingInfo);
- }
- }
- private final static class EnclosingMethodInfo {
- private Class<?> enclosingClass;
- private String name;
- private String descriptor;
- private EnclosingMethodInfo(Object[] enclosingInfo) {
- if (enclosingInfo.length != 3)
- throw new InternalError("Malformed enclosing method information");
- try {
- // The array is expected to have three elements:
- // the immediately enclosing class
- enclosingClass = (Class<?>) enclosingInfo[0];
- assert(enclosingClass != null);
- // the immediately enclosing method or constructor's
- // name (can be null).
- name = (String) enclosingInfo[1];
- // the immediately enclosing method or constructor's
- // descriptor (null iff name is).
- descriptor = (String) enclosingInfo[2];
- assert((name != null && descriptor != null) || name == descriptor);
- } catch (ClassCastException cce) {
- throw new InternalError("Invalid type in enclosing method information", cce);
- }
- }
- boolean isPartial() {
- return enclosingClass == null || name == null || descriptor == null;
- }
- boolean isConstructor() { return !isPartial() && "<init>".equals(name); }
- boolean isMethod() { return !isPartial() && !isConstructor() && !"<clinit>".equals(name); }
- Class<?> getEnclosingClass() { return enclosingClass; }
- String getName() { return name; }
- String getDescriptor() { return descriptor; }
- }
- private static Class<?> toClass(Type o) {
- if (o instanceof GenericArrayType)
- return Array.newInstance(toClass(((GenericArrayType)o).getGenericComponentType()),
- 0)
- .getClass();
- return (Class<?>)o;
- }
- /**
- * If this {@code Class} object represents a local or anonymous
- * class within a constructor, returns a {@link
- * java.lang.reflect.Constructor Constructor} object representing
- * the immediately enclosing constructor of the underlying
- * class. Returns {@code null} otherwise. In particular, this
- * method returns {@code null} if the underlying class is a local
- * or anonymous class immediately enclosed by a type declaration,
- * instance initializer or static initializer.
- *
- * @return the immediately enclosing constructor of the underlying class, if
- * that class is a local or anonymous class; otherwise {@code null}.
- * @since 1.5
- */
- public Constructor<?> getEnclosingConstructor() {
- EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
- if (enclosingInfo == null)
- return null;
- else {
- if (!enclosingInfo.isConstructor())
- return null;
- ConstructorRepository typeInfo = ConstructorRepository.make(enclosingInfo.getDescriptor(),
- getFactory());
- Type [] parameterTypes = typeInfo.getParameterTypes();
- Class<?>[] parameterClasses = new Class<?>[parameterTypes.length];
- // Convert Types to Classes; returned types *should*
- // be class objects since the methodDescriptor's used
- // don't have generics information
- for(int i = 0; i < parameterClasses.length; i++)
- parameterClasses[i] = toClass(parameterTypes[i]);
- /*
- * Loop over all declared constructors; match number
- * of and type of parameters.
- */
- for(Constructor<?> c: enclosingInfo.getEnclosingClass().getDeclaredConstructors()) {
- Class<?>[] candidateParamClasses = c.getParameterTypes();
- if (candidateParamClasses.length == parameterClasses.length) {
- boolean matches = true;
- for(int i = 0; i < candidateParamClasses.length; i++) {
- if (!candidateParamClasses[i].equals(parameterClasses[i])) {
- matches = false;
- break;
- }
- }
- if (matches)
- return c;
- }
- }
- throw new InternalError("Enclosing constructor not found");
- }
- }
- /**
- * If the class or interface represented by this {@code Class} object
- * is a member of another class, returns the {@code Class} object
- * representing the class in which it was declared. This method returns
- * null if this class or interface is not a member of any other class. If
- * this {@code Class} object represents an array class, a primitive
- * type, or void,then this method returns null.
- *
- * @return the declaring class for this class
- * @since JDK1.1
- */
- public native Class<?> getDeclaringClass();
- /**
- * Returns the immediately enclosing class of the underlying
- * class. If the underlying class is a top level class this
- * method returns {@code null}.
- * @return the immediately enclosing class of the underlying class
- * @since 1.5
- */
- public Class<?> getEnclosingClass() {
- // There are five kinds of classes (or interfaces):
- // a) Top level classes
- // b) Nested classes (static member classes)
- // c) Inner classes (non-static member classes)
- // d) Local classes (named classes declared within a method)
- // e) Anonymous classes
- // JVM Spec 4.8.6: A class must have an EnclosingMethod
- // attribute if and only if it is a local class or an
- // anonymous class.
- EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
- if (enclosingInfo == null) {
- // This is a top level or a nested class or an inner class (a, b, or c)
- return getDeclaringClass();
- } else {
- Class<?> enclosingClass = enclosingInfo.getEnclosingClass();
- // This is a local class or an anonymous class (d or e)
- if (enclosingClass == this || enclosingClass == null)
- throw new InternalError("Malformed enclosing method information");
- else
- return enclosingClass;
- }
- }
- /**
- * Returns the simple name of the underlying class as given in the
- * source code. Returns an empty string if the underlying class is
- * anonymous.
- *
- * <p>The simple name of an array is the simple name of the
- * component type with "[]" appended. In particular the simple
- * name of an array whose component type is anonymous is "[]".
- *
- * @return the simple name of the underlying class
- * @since 1.5
- */
- public String getSimpleName() {
- if (isArray())
- return getComponentType().getSimpleName()+"[]";
- String simpleName = getSimpleBinaryName();
- if (simpleName == null) { // top level class
- simpleName = getName();
- return simpleName.substring(simpleName.lastIndexOf(".")+1); // strip the package name
- }
- // According to JLS3 "Binary Compatibility" (13.1) the binary
- // name of non-package classes (not top level) is the binary
- // name of the immediately enclosing class followed by a '$' followed by:
- // (for nested and inner classes): the simple name.
- // (for local classes): 1 or more digits followed by the simple name.
- // (for anonymous classes): 1 or more digits.
- // Since getSimpleBinaryName() will strip the binary name of
- // the immediatly enclosing class, we are now looking at a
- // string that matches the regular expression "\$[0-9]*"
- // followed by a simple name (considering the simple of an
- // anonymous class to be the empty string).
- // Remove leading "\$[0-9]*" from the name
- int length = simpleName.length();
- if (length < 1 || simpleName.charAt(0) != '$')
- throw new InternalError("Malformed class name");
- int index = 1;
- while (index < length && isAsciiDigit(simpleName.charAt(index)))
- index++;
- // Eventually, this is the empty string iff this is an anonymous class
- return simpleName.substring(index);
- }
- /**
- * Character.isDigit answers {@code true} to some non-ascii
- * digits. This one does not.
- */
- private static boolean isAsciiDigit(char c) {
- return '0' <= c && c <= '9';
- }
- /**
- * Returns the canonical name of the underlying class as
- * defined by the Java Language Specification. Returns null if
- * the underlying class does not have a canonical name (i.e., if
- * it is a local or anonymous class or an array whose component
- * type does not have a canonical name).
- * @return the canonical name of the underlying class if it exists, and
- * {@code null} otherwise.
- * @since 1.5
- */
- public String getCanonicalName() {
- if (isArray()) {
- String canonicalName = getComponentType().getCanonicalName();
- if (canonicalName != null)
- return canonicalName + "[]";
- else
- return null;
- }
- if (isLocalOrAnonymousClass())
- return null;
- Class<?> enclosingClass = getEnclosingClass();
- if (enclosingClass == null) { // top level class
- return getName();
- } else {
- …
Large files files are truncated, but you can click here to view the full file