Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  Class.java   Sprache: JAVA

 
/*
 * Copyright (c) 1994, 2022, 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.annotation.Annotation;
import java.lang.constant.ClassDesc;
import java.lang.invoke.TypeDescriptor;
import java.lang.invoke.MethodHandles;
import java.lang.module.ModuleReader;
import java.lang.ref.SoftReference;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectStreamField;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.AnnotatedType;
import java.lang.reflect.AccessFlag;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Executable;
import java.lang.reflect.Field;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.GenericDeclaration;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
import java.lang.reflect.RecordComponent;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.constant.Constable;
import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

import jdk.internal.loader.BootLoader;
import jdk.internal.loader.BuiltinClassLoader;
import jdk.internal.misc.Unsafe;
import jdk.internal.module.Resources;
import jdk.internal.reflect.CallerSensitive;
import jdk.internal.reflect.CallerSensitiveAdapter;
import jdk.internal.reflect.ConstantPool;
import jdk.internal.reflect.Reflection;
import jdk.internal.reflect.ReflectionFactory;
import jdk.internal.vm.annotation.ForceInline;
import jdk.internal.vm.annotation.IntrinsicCandidate;
import sun.invoke.util.Wrapper;
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 sun.reflect.annotation.*;
import sun.reflect.misc.ReflectUtil;

/**
 * Instances of the class {@code Class} represent classes and
 * interfaces in a running Java application. An enum class and a record
 * class are kinds of class; an annotation interface 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 a {@code Class}
 * object is constructed automatically by the Java Virtual Machine when
 * a class is derived from the bytes of a {@code class} file through
 * the invocation of one of the following methods:
 * <ul>
 * <li> {@link ClassLoader#defineClass(String, byte[], int, int) ClassLoader::defineClass}
 * <li> {@link java.lang.invoke.MethodHandles.Lookup#defineClass(byte[])
 *      java.lang.invoke.MethodHandles.Lookup::defineClass}
 * <li> {@link java.lang.invoke.MethodHandles.Lookup#defineHiddenClass(byte[], boolean, MethodHandles.Lookup.ClassOption...)
 *      java.lang.invoke.MethodHandles.Lookup::defineHiddenClass}
 * </ul>
 *
 * <p> The methods of class {@code Class} expose many characteristics of a
 * class or interface. Most characteristics are derived from the {@code class}
 * file that the class loader passed to the Java Virtual Machine or
 * from the {@code class} file passed to {@code Lookup::defineClass}
 * or {@code Lookup::defineHiddenClass}.
 * A few characteristics are determined by the class loading environment
 * at run time, such as the module returned by {@link #getModule() getModule()}.
 *
 * <p> The following example uses a {@code Class} object to print the
 * class name of an object:
 *
 * <blockquote><pre>
 *     void printClassName(Object obj) {
 *         System.out.println("The class of " + obj +
 *                            " is " + obj.getClass().getName());
 *     }
 * </pre></blockquote>
 *
 * It is also possible to get the {@code Class} object for a named
 * class or interface (or for {@code void}) using a <i>class literal</i>.
 * For example:
 *
 * <blockquote>
 *     {@code System.out.println("The name of class Foo is: "+Foo.class.getName());}
 * </blockquote>
 *
 * <p> Some methods of class {@code Class} expose whether the declaration of
 * a class or interface in Java source code was <em>enclosed</em> within
 * another declaration. Other methods describe how a class or interface
 * is situated in a <em>nest</em>. A <a id="nest">nest</a> is a set of
 * classes and interfaces, in the same run-time package, that
 * allow mutual access to their {@code private} members.
 * The classes and interfaces are known as <em>nestmates</em>.
 * One nestmate acts as the
 * <em>nest host</em>, and enumerates the other nestmates which
 * belong to the nest; each of them in turn records it as the nest host.
 * The classes and interfaces which belong to a nest, including its host, are
 * determined when
 * {@code class} files are generated, for example, a Java compiler
 * will typically record a top-level class as the host of a nest where the
 * other members are the classes and interfaces whose declarations are
 * enclosed within the top-level class declaration.
 *
 * <p> A class or interface created by the invocation of
 * {@link java.lang.invoke.MethodHandles.Lookup#defineHiddenClass(byte[], boolean, MethodHandles.Lookup.ClassOption...)
 * Lookup::defineHiddenClass} is a {@linkplain Class#isHidden() <em>hidden</em>}
 * class or interface.
 * All kinds of class, including enum classes and record classes, may be
 * hidden classes; all kinds of interface, including annotation interfaces,
 * may be hidden interfaces.
 *
 * The {@linkplain #getName() name of a hidden class or interface} is
 * not a <a href="ClassLoader.html#binary-name">binary name</a>,
 * which means the following:
 * <ul>
 * <li>A hidden class or interface cannot be referenced by the constant pools
 *     of other classes and interfaces.
 * <li>A hidden class or interface cannot be described in
 *     {@linkplain java.lang.constant.ConstantDesc <em>nominal form</em>} by
 *     {@link #describeConstable() Class::describeConstable},
 *     {@link ClassDesc#of(String) ClassDesc::of}, or
 *     {@link ClassDesc#ofDescriptor(String) ClassDesc::ofDescriptor}.
 * <li>A hidden class or interface cannot be discovered by {@link #forName Class::forName}
 *     or {@link ClassLoader#loadClass(String, boolean) ClassLoader::loadClass}.
 * </ul>
 *
 * A hidden class or interface is never an array class, but may be
 * the element type of an array. In all other respects, the fact that
 * a class or interface is hidden has no bearing on the characteristics
 * exposed by the methods of class {@code Class}.
 *
 * @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.
 *
 * @see     java.lang.ClassLoader#defineClass(byte[], int, int)
 * @since   1.0
 * @jls 15.8.2 Class Literals
 */

public final class Class<T> implements java.io.Serializable,
                              GenericDeclaration,
                              Type,
                              AnnotatedElement,
                              TypeDescriptor.OfField<Class<?>>,
                              Constable {
    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();
    }

    /*
     * Private constructor. Only the Java Virtual Machine creates Class objects.
     * This constructor is not used and prevents the default constructor being
     * generated.
     */

    private Class(ClassLoader loader, Class<?> arrayComponentType) {
        // Initialize final field for classLoader.  The initialization value of non-null
        // prevents future JIT optimizations from assuming this final field is null.
        classLoader = loader;
        componentType = arrayComponentType;
    }

    /**
     * Converts the object to a string. The string representation is the
     * string "class" or "interface", followed by a space, and then by the
     * 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". If this {@code Class} object represents an array type,
     * this method returns "class " followed by {@code getName}.
     *
     * @return a string representation of this {@code Class} object.
     */

    public String toString() {
        String kind = isInterface() ? "interface " : isPrimitive() ? "" : "class ";
        return kind.concat(getName());
    }

    /**
     * Returns a string describing this {@code Class}, including
     * information about modifiers and type parameters.
     *
     * The string is formatted as a list of type modifiers, if any,
     * followed by the kind of type (empty string for primitive types
     * and {@code class}, {@code enum}, {@code interface},
     * {@code @interface}, or {@code record} as appropriate), followed
     * by the type's name, followed by an angle-bracketed
     * comma-separated list of the type's type parameters, if any,
     * including informative bounds on the type parameters, if any.
     *
     * A space is used to separate modifiers from one another and to
     * separate any modifiers from the kind of type. The modifiers
     * occur in canonical order. If there are no type parameters, the
     * type parameter list is elided.
     *
     * For an array type, the string starts with the type name,
     * followed by an angle-bracketed comma-separated list of the
     * type's type parameters, if any, followed by a sequence of
     * {@code []} characters, one set of brackets per dimension of
     * the array.
     *
     * <p>Note that since information about the runtime representation
     * of a type is being generated, modifiers not present on the
     * originating source code or illegal on the originating source
     * code may be present.
     *
     * @return a string describing this {@code Class}, including
     * information about modifiers and type parameters
     *
     * @since 1.8
     */

    public String toGenericString() {
        if (isPrimitive()) {
            return toString();
        } else {
            StringBuilder sb = new StringBuilder();
            Class<?> component = this;
            int arrayDepth = 0;

            if (isArray()) {
                do {
                    arrayDepth++;
                    component = component.getComponentType();
                } while (component.isArray());
                sb.append(component.getName());
            } else {
                // Class modifiers are a superset of interface modifiers
                int modifiers = getModifiers() & Modifier.classModifiers();
                if (modifiers != 0) {
                    sb.append(Modifier.toString(modifiers));
                    sb.append(' ');
                }

                if (isAnnotation()) {
                    sb.append('@');
                }
                if (isInterface()) { // Note: all annotation interfaces are interfaces
                    sb.append("interface");
                } else {
                    if (isEnum())
                        sb.append("enum");
                    else if (isRecord())
                        sb.append("record");
                    else
                        sb.append("class");
                }
                sb.append(' ');
                sb.append(getName());
            }

            TypeVariable<?>[] typeparms = component.getTypeParameters();
            if (typeparms.length > 0) {
                sb.append(Arrays.stream(typeparms)
                          .map(Class::typeVarBounds)
                          .collect(Collectors.joining(",""<"">")));
            }

            if (arrayDepth > 0) sb.append("[]".repeat(arrayDepth));

            return sb.toString();
        }
    }

    static String typeVarBounds(TypeVariable<?> typeVar) {
        Type[] bounds = typeVar.getBounds();
        if (bounds.length == 1 && bounds[0].equals(Object.class)) {
            return typeVar.getName();
        } else {
            return typeVar.getName() + " extends " +
                Arrays.stream(bounds)
                .map(Type::getTypeName)
                .collect(Collectors.joining(" & "));
        }
    }

    /**
     * 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.
     *
     * <p>
     * In cases where this method is called from a context where there is no
     * caller frame on the stack (e.g. when called directly from a JNI
     * attached thread), the system class loader is used.
     *
     * @param      className   the fully qualified name of the desired class.
     * @return     the {@code Class} object for the class with the
     *             specified name.
     * @throws    LinkageError if the linkage fails
     * @throws    ExceptionInInitializerError if the initialization provoked
     *            by this method fails
     * @throws    ClassNotFoundException if the class cannot be located
     *
     * @jls 12.2 Loading of Classes and Interfaces
     * @jls 12.3 Linking of Classes and Interfaces
     * @jls 12.4 Initialization of Classes and Interfaces
     */

    @CallerSensitive
    public static Class<?> forName(String className)
                throws ClassNotFoundException {
        Class<?> caller = Reflection.getCallerClass();
        return forName(className, caller);
    }

    // Caller-sensitive adapter method for reflective invocation
    @CallerSensitiveAdapter
    private static Class<?> forName(String className, Class<?> caller)
            throws ClassNotFoundException {
        ClassLoader loader = (caller == null) ? ClassLoader.getSystemClassLoader()
                                              : ClassLoader.getClassLoader(caller);
        return forName0(className, true, loader, caller);
    }

    /**
     * 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 and load 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 {@jls 12.2}, {@jls
     * 12.3}, and {@jls 12.4} of <cite>The Java Language
     * Specification</cite>.
     * Note that this method does not check whether the requested class
     * is accessible to its caller.
     *
     * @param name       fully qualified name of the desired class

     * @param initialize if {@code true} the class will be initialized
     *                   (which implies linking). See Section {@jls
     *                   12.4} of <cite>The Java Language
     *                   Specification</cite>.
     * @param loader     class loader from which the class must be loaded
     * @return           class object representing the desired class
     *
     * @throws    LinkageError if the linkage fails
     * @throws    ExceptionInInitializerError if the initialization provoked
     *            by this method fails
     * @throws    ClassNotFoundException if the class cannot be located by
     *            the specified class loader
     * @throws    SecurityException
     *            if a security manager is present, and the {@code loader} is
     *            {@code null}, and the caller's class loader is not
     *            {@code null}, and the caller does not have the
     *            {@link RuntimePermission}{@code ("getClassLoader")}
     *
     * @see       java.lang.Class#forName(String)
     * @see       java.lang.ClassLoader
     *
     * @jls 12.2 Loading of Classes and Interfaces
     * @jls 12.3 Linking of Classes and Interfaces
     * @jls 12.4 Initialization of Classes and Interfaces
     * @since     1.2
     */

    @CallerSensitive
    public static Class<?> forName(String name, boolean initialize,
                                   ClassLoader loader)
        throws ClassNotFoundException
    {
        Class<?> caller = null;
        @SuppressWarnings("removal")
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            // Reflective call to get caller class is only needed if a security manager
            // is present.  Avoid the overhead of making this call otherwise.
            caller = Reflection.getCallerClass();
        }
        return forName(name, initialize, loader, caller);
    }

    // Caller-sensitive adapter method for reflective invocation
    @CallerSensitiveAdapter
    private static Class<?> forName(String name, boolean initialize, ClassLoader loader, Class<?> caller)
            throws ClassNotFoundException
    {
        @SuppressWarnings("removal")
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            // Reflective call to get caller class is only needed if a security manager
            // is present.  Avoid the overhead of making this call otherwise.
            if (loader == null) {
                ClassLoader ccl = ClassLoader.getClassLoader(caller);
                if (ccl != null) {
                    sm.checkPermission(
                            SecurityConstants.GET_CLASSLOADER_PERMISSION);
                }
            }
        }
        return forName0(name, initialize, loader, caller);
    }

    /** Called after security check for system loader access checks have been made. */
    private static native Class<?> forName0(String name, boolean initialize,
                                            ClassLoader loader,
                                            Class<?> caller)
        throws ClassNotFoundException;


    /**
     * Returns the {@code Class} with the given <a href="ClassLoader.html#binary-name">
     * binary name</a> in the given module.
     *
     * <p> This method attempts to locate and load the class or interface.
     * It does not link the class, and does not run the class initializer.
     * If the class is not found, this method returns {@code null}. </p>
     *
     * <p> If the class loader of the given module defines other modules and
     * the given name is a class defined in a different module, this method
     * returns {@code null} after the class is loaded. </p>
     *
     * <p> This method does not check whether the requested class is
     * accessible to its caller. </p>
     *
     * @apiNote
     * This method returns {@code null} on failure rather than
     * throwing a {@link ClassNotFoundException}, as is done by
     * the {@link #forName(String, boolean, ClassLoader)} method.
     * The security check is a stack-based permission check if the caller
     * loads a class in another module.
     *
     * @param  module   A module
     * @param  name     The <a href="ClassLoader.html#binary-name">binary name</a>
     *                  of the class
     * @return {@code Class} object of the given name defined in the given module;
     *         {@code null} if not found.
     *
     * @throws NullPointerException if the given module or name is {@code null}
     *
     * @throws LinkageError if the linkage fails
     *
     * @throws SecurityException
     *         <ul>
     *         <li> if the caller is not the specified module and
     *         {@code RuntimePermission("getClassLoader")} permission is denied; or</li>
     *         <li> access to the module content is denied. For example,
     *         permission check will be performed when a class loader calls
     *         {@link ModuleReader#open(String)} to read the bytes of a class file
     *         in a module.</li>
     *         </ul>
     *
     * @jls 12.2 Loading of Classes and Interfaces
     * @jls 12.3 Linking of Classes and Interfaces
     * @since 9
     */

    @SuppressWarnings("removal")
    @CallerSensitive
    public static Class<?> forName(Module module, String name) {
        Class<?> caller = null;
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            caller = Reflection.getCallerClass();
        }
        return forName(module, name, caller);
    }

    // Caller-sensitive adapter method for reflective invocation
    @SuppressWarnings("removal")
    @CallerSensitiveAdapter
    private static Class<?> forName(Module module, String name, Class<?> caller) {
        Objects.requireNonNull(module);
        Objects.requireNonNull(name);

        ClassLoader cl;
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            if (caller != null && caller.getModule() != module) {
                // if caller is null, Class.forName is the last java frame on the stack.
                // java.base has all permissions
                sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
            }
            PrivilegedAction<ClassLoader> pa = module::getClassLoader;
            cl = AccessController.doPrivileged(pa);
        } else {
            cl = module.getClassLoader();
        }

        if (cl != null) {
            return cl.loadClass(module, name);
        } else {
            return BootLoader.loadClass(module, name);
        }
    }

    /**
     * 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.
     *
     * @deprecated 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}.
     *
     * <p>The call
     *
     * <pre>{@code
     * clazz.newInstance()
     * }</pre>
     *
     * can be replaced by
     *
     * <pre>{@code
     * clazz.getDeclaredConstructor().newInstance()
     * }</pre>
     *
     * The latter sequence of calls is inferred to be able to throw
     * the additional exception types {@link
     * InvocationTargetException} and {@link
     * NoSuchMethodException}. Both of these exception types are
     * subclasses of {@link ReflectiveOperationException}.
     *
     * @return  a newly allocated instance of the class represented by this
     *          object.
     * @throws  IllegalAccessException  if the class or its nullary
     *          constructor is not accessible.
     * @throws  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.
     * @throws  ExceptionInInitializerError if the initialization
     *          provoked by this method fails.
     * @throws  SecurityException
     *          If a security manager, <i>s</i>, is present and
     *          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.
     */

    @SuppressWarnings("removal")
    @CallerSensitive
    @Deprecated(since="9")
    public T newInstance()
        throws InstantiationException, IllegalAccessException
    {
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            checkMemberAccess(sm, Member.PUBLIC, Reflection.getCallerClass(), false);
        }

        // Constructor lookup
        Constructor<T> tmpConstructor = cachedConstructor;
        if (tmpConstructor == 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 = getReflectionFactory().copyConstructor(
                    getConstructor0(empty, Member.DECLARED));
                // Disable accessibility checks on the constructor
                // access check is done with the true caller
                java.security.AccessController.doPrivileged(
                    new java.security.PrivilegedAction<>() {
                        public Void run() {
                                c.setAccessible(true);
                                return null;
                            }
                        });
                cachedConstructor = tmpConstructor = c;
            } catch (NoSuchMethodException e) {
                throw (InstantiationException)
                    new InstantiationException(getName()).initCause(e);
            }
        }

        try {
            Class<?> caller = Reflection.getCallerClass();
            return getReflectionFactory().newInstance(tmpConstructor, null, caller);
        } catch (InvocationTargetException e) {
            Unsafe.getUnsafe().throwException(e.getTargetException());
            // Not reached
            return null;
        }
    }

    private transient volatile Constructor<T> cachedConstructor;

    /**
     * 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 1.1
     */

    @IntrinsicCandidate
    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 <cite>The Java Language
     * Specification</cite>, sections {@jls 5.1.1} and {@jls 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
     * @throws    NullPointerException if the specified Class parameter is
     *            null.
     * @since     1.1
     */

    @IntrinsicCandidate
    public native boolean isAssignableFrom(Class<?> cls);


    /**
     * Determines if this {@code Class} object represents an
     * interface type.
     *
     * @return  {@code true} if this {@code Class} object represents an interface;
     *          {@code false} otherwise.
     */

    @IntrinsicCandidate
    public native boolean isInterface();


    /**
     * Determines if this {@code Class} object represents an array class.
     *
     * @return  {@code true} if this {@code Class} object represents an array class;
     *          {@code false} otherwise.
     * @since   1.1
     */

    @IntrinsicCandidate
    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 1.1
     */

    @IntrinsicCandidate
    public native boolean isPrimitive();

    /**
     * Returns true if this {@code Class} object represents an annotation
     * interface.  Note that if this method returns true, {@link #isInterface()}
     * would also return true, as all annotation interfaces are also interfaces.
     *
     * @return {@code true} if this {@code Class} object represents an annotation
     *      interface; {@code false} otherwise
     * @since 1.5
     */

    public boolean isAnnotation() {
        return (getModifiers() & ANNOTATION) != 0;
    }

    /**
     *{@return {@code true} if and only if this class has the synthetic modifier
     * bit set}
     *
     * @jls 13.1 The Form of a Binary
     * @jvms 4.1 The {@code ClassFile} Structure
     * @see <a
     * href="{@docRoot}/java.base/java/lang/reflect/package-summary.html#LanguageJvmModel">Java
     * programming language and JVM modeling in core reflection</a>
     * @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.
     *
     * <p> If this {@code Class} object represents a class or interface,
     * not an array class, then:
     * <ul>
     * <li> If the class or interface is not {@linkplain #isHidden() hidden},
     *      then the <a href="ClassLoader.html#binary-name">binary name</a>
     *      of the class or interface is returned.
     * <li> If the class or interface is hidden, then the result is a string
     *      of the form: {@code N + '/' + <suffix>}
     *      where {@code N} is the <a href="ClassLoader.html#binary-name">binary name</a>
     *      indicated by the {@code class} file passed to
     *      {@link java.lang.invoke.MethodHandles.Lookup#defineHiddenClass(byte[], boolean, MethodHandles.Lookup.ClassOption...)
     *      Lookup::defineHiddenClass}, and {@code <suffix>} is an unqualified name.
     * </ul>
     *
     * <p> If this {@code Class} object represents an array class, then
     * the result is a string consisting of one or more '{@code [}' characters
     * representing the depth of the array nesting, followed by the element
     * type as encoded using the following table:
     *
     * <blockquote><table class="striped">
     * <caption style="display:none">Element types and encodings</caption>
     * <thead>
     * <tr><th scope="col"> Element Type <th scope="col"> Encoding
     * </thead>
     * <tbody style="text-align:left">
     * <tr><th scope="row"> {@code boolean} <td style="text-align:center"> {@code Z}
     * <tr><th scope="row"> {@code byte}    <td style="text-align:center"> {@code B}
     * <tr><th scope="row"> {@code char}    <td style="text-align:center"> {@code C}
     * <tr><th scope="row"> class or interface with <a href="ClassLoader.html#binary-name">binary name</a> <i>N</i>
     *                                      <td style="text-align:center"> {@code L}<em>N</em>{@code ;}
     * <tr><th scope="row"> {@code double}  <td style="text-align:center"> {@code D}
     * <tr><th scope="row"> {@code float}   <td style="text-align:center"> {@code F}
     * <tr><th scope="row"> {@code int}     <td style="text-align:center"> {@code I}
     * <tr><th scope="row"> {@code long}    <td style="text-align:center"> {@code J}
     * <tr><th scope="row"> {@code short}   <td style="text-align:center"> {@code S}
     * </tbody>
     * </table></blockquote>
     *
     * <p> If this {@code Class} object represents a primitive type or {@code void},
     * then the result is a string with the same spelling as the Java language
     * keyword which corresponds to the primitive type or {@code void}.
     *
     * <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, interface, or other entity
     *          represented by this {@code Class} object.
     * @jls 13.1 The Form of a Binary
     */

    public String getName() {
        String name = this.name;
        return name != null ? name : initClassName();
    }

    // Cache the name to reduce the number of calls into the VM.
    // This field would be set by VM itself during initClassName call.
    private transient String name;
    private native String initClassName();

    /**
     * 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 this {@code Class} object
     * represents a primitive type or void, null is returned.
     *
     * @return  the class loader that loaded the class or interface
     *          represented by this {@code Class} object.
     * @throws  SecurityException
     *          if a security manager is present, and the caller's class loader
     *          is not {@code null} and is not the same as or an ancestor of the
     *          class loader for the class whose class loader is requested,
     *          and the caller does not have the
     *          {@link RuntimePermission}{@code ("getClassLoader")}
     * @see java.lang.ClassLoader
     * @see SecurityManager#checkPermission
     * @see java.lang.RuntimePermission
     */

    @CallerSensitive
    @ForceInline // to ensure Reflection.getCallerClass optimization
    public ClassLoader getClassLoader() {
        ClassLoader cl = classLoader;
        if (cl == null)
            return null;
        @SuppressWarnings("removal")
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            ClassLoader.checkClassLoaderPermission(cl, Reflection.getCallerClass());
        }
        return cl;
    }

    // Package-private to allow ClassLoader access
    ClassLoader getClassLoader0() { return classLoader; }

    /**
     * Returns the module that this class or interface is a member of.
     *
     * If this class represents an array type then this method returns the
     * {@code Module} for the element type. If this class represents a
     * primitive type or void, then the {@code Module} object for the
     * {@code java.base} module is returned.
     *
     * If this class is in an unnamed module then the {@linkplain
     * ClassLoader#getUnnamedModule() unnamed} {@code Module} of the class
     * loader for this class is returned.
     *
     * @return the module that this class or interface is a member of
     *
     * @since 9
     */

    public Module getModule() {
        return module;
    }

    // set by VM
    private transient Module module;

    // Initialized in JVM not by private constructor
    // This field is filtered from reflection access, i.e. getDeclaredField
    // will throw NoSuchFieldException
    private final ClassLoader classLoader;

    // Set by VM
    private transient Object classData;

    // package-private
    Object getClassData() {
        return classData;
    }

    /**
     * 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 section {@jvms 4.7.9} of
     *     <cite>The Java Virtual Machine Specification</cite>
     * @since 1.5
     */

    @SuppressWarnings("unchecked")
    public TypeVariable<Class<T>>[] getTypeParameters() {
        ClassRepository info = getGenericInfo();
        if (info != null)
            return (TypeVariable<Class<T>>[])info.getTypeParameters();
        else
            return (TypeVariable<Class<T>>[])new TypeVariable<?>[0];
    }


    /**
     * Returns the {@code Class} representing the direct 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 {@code Class} object represents an array class
     * then the {@code Class} object representing the {@code Object} class is
     * returned.
     *
     * @return the direct superclass of the class represented by this {@code Class} object
     */

    @IntrinsicCandidate
    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} object.
     *
     * <p>If the superclass is a parameterized type, the {@code Type}
     * object returned must accurately reflect the actual type
     * arguments 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} object represents either the {@code Object}
     * class, an interface, a primitive type, or void, then null is
     * returned.  If this {@code Class} 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
     *     section {@jvms 4.7.9} of <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 direct superclass of the class represented by this {@code Class} object
     * @since 1.5
     */

    public Type getGenericSuperclass() {
        ClassRepository info = getGenericInfo();
        if (info == null) {
            return getSuperclass();
        }

        // Historical irregularity:
        // Generic signature marks interfaces with superclass = Object
        // but this API returns null for interfaces
        if (isInterface()) {
            return null;
        }

        return info.getSuperclass();
    }

    /**
     * Gets the package of this class.
     *
     * <p>If this class represents an array type, a primitive type or void,
     * this method returns {@code null}.
     *
     * @return the package of this class.
     * @revised 9
     */

    public Package getPackage() {
        if (isPrimitive() || isArray()) {
            return null;
        }
        ClassLoader cl = classLoader;
        return cl != null ? cl.definePackage(this)
                          : BootLoader.definePackage(this);
    }

    /**
     * Returns the fully qualified package name.
     *
     * <p> If this class is a top level class, then this method returns the fully
     * qualified name of the package that the class is a member of, or the
     * empty string if the class is in an unnamed package.
     *
     * <p> If this class is a member class, then this method is equivalent to
     * invoking {@code getPackageName()} on the {@linkplain #getEnclosingClass
     * enclosing class}.
     *
     * <p> If this class is a {@linkplain #isLocalClass local class} or an {@linkplain
     * #isAnonymousClass() anonymous class}, then this method is equivalent to
     * invoking {@code getPackageName()} on the {@linkplain #getDeclaringClass
     * declaring class} of the {@linkplain #getEnclosingMethod enclosing method} or
     * {@linkplain #getEnclosingConstructor enclosing constructor}.
     *
     * <p> If this class represents an array type then this method returns the
     * package name of the element type. If this class represents a primitive
     * type or void then the package name "{@code java.lang}" is returned.
     *
     * @return the fully qualified package name
     *
     * @since 9
     * @jls 6.7 Fully Qualified Names
     */

    public String getPackageName() {
        String pn = this.packageName;
        if (pn == null) {
            Class<?> c = isArray() ? elementType() : this;
            if (c.isPrimitive()) {
                pn = "java.lang";
            } else {
                String cn = c.getName();
                int dot = cn.lastIndexOf('.');
                pn = (dot != -1) ? cn.substring(0, dot).intern() : "";
            }
            this.packageName = pn;
        }
        return pn;
    }

    // cached package name
    private transient String packageName;

    /**
     * Returns the interfaces directly implemented by the class or interface
     * represented by this {@code Class} object.
     *
     * <p>If this {@code Class} object represents a class, the return value is an array
     * containing objects representing all interfaces directly 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 {@code Class} 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 {@code Class} 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 {@code Class} object.
     *
     * <p>If this {@code Class} object represents a class or interface that implements no
     * interfaces, the method returns an array of length 0.
     *
     * <p>If this {@code Class} object represents a primitive type or void, the method
     * returns an array of length 0.
     *
     * <p>If this {@code Class} object represents an array type, the
     * interfaces {@code Cloneable} and {@code java.io.Serializable} are
     * returned in that order.
     *
     * @return an array of interfaces directly implemented by this class
     */

    public Class<?>[] getInterfaces() {
        // defensively copy before handing over to user code
        return getInterfaces(true);
    }

    private Class<?>[] getInterfaces(boolean cloneArray) {
        ReflectionData<T> rd = reflectionData();
        if (rd == null) {
            // no cloning required
            return getInterfaces0();
        } else {
            Class<?>[] interfaces = rd.interfaces;
            if (interfaces == null) {
                interfaces = getInterfaces0();
                rd.interfaces = interfaces;
            }
            // defensively copy if requested
            return cloneArray ? interfaces.clone() : interfaces;
        }
    }

    private native Class<?>[] getInterfaces0();

    /**
     * Returns the {@code Type}s representing the interfaces
     * directly implemented by the class or interface represented by
     * this {@code Class} object.
     *
     * <p>If a superinterface is a parameterized type, the
     * {@code Type} object returned for it must accurately reflect
     * the actual type arguments 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 {@code Class} object represents a class, the return value is an array
     * containing objects representing all interfaces directly 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 {@code Class} object.
     *
     * <p>If this {@code Class} 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 {@code Class} object.
     *
     * <p>If this {@code Class} object represents a class or interface that implements no
     * interfaces, the method returns an array of length 0.
     *
     * <p>If this {@code Class} object represents a primitive type or void, the method
     * returns an array of length 0.
     *
     * <p>If this {@code Class} object represents an array type, the
     * interfaces {@code Cloneable} and {@code java.io.Serializable} are
     * returned in that order.
     *
     * @throws java.lang.reflect.GenericSignatureFormatError
     *     if the generic class signature does not conform to the
     *     format specified in section {@jvms 4.7.9} of <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 directly implemented by this class
     * @since 1.5
     */

    public Type[] getGenericInterfaces() {
        ClassRepository info = getGenericInfo();
        return (info == null) ?  getInterfaces() : info.getSuperInterfaces();
    }


    /**
     * 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 1.1
     */

    public Class<?> getComponentType() {
        // Only return for array types. Storage may be reused for Class for instance types.
        if (isArray()) {
            return componentType;
        } else {
            return null;
        }
    }

    private final Class<?> componentType;

    /*
     * Returns the {@code Class} representing the element type of an array class.
     * If this class does not represent an array class, then this method returns
     * {@code null}.
     */

    private Class<?> elementType() {
        if (!isArray()) return null;

        Class<?> c = this;
        while (c.isArray()) {
            c = c.getComponentType();
        }
        return c;
    }

    /**
     * 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:
     * <ul>
     * <li> its {@code public}, {@code private} and {@code protected}
     *      modifiers are the same as those of its component type
     * <li> its {@code abstract} and {@code final} modifiers are always
     *      {@code true}
     * <li> its interface modifier is always {@code false}, even when
     *      the component type is an interface
     * </ul>
     * If this {@code Class} object represents a primitive type or
     * void, its {@code public}, {@code abstract}, and {@code final}
     * modifiers are always {@code true}.
     * For {@code Class} objects representing void, primitive types, and
     * arrays, the values of other modifiers are {@code false} other
     * than as specified above.
     *
     * <p> The modifier encodings are defined in section {@jvms 4.1}
     * of <cite>The Java Virtual Machine Specification</cite>.
     *
     * @return the {@code int} representing the modifiers for this class
     * @see     java.lang.reflect.Modifier
     * @see #accessFlags()
     * @see <a
     * href="{@docRoot}/java.base/java/lang/reflect/package-summary.html#LanguageJvmModel">Java
     * programming language and JVM modeling in core reflection</a>
     * @since 1.1
     * @jls 8.1.1 Class Modifiers
     * @jls 9.1.1. Interface Modifiers
     * @jvms 4.1 The {@code ClassFile} Structure
     */

    @IntrinsicCandidate
    public native int getModifiers();

    /**
     * {@return an unmodifiable set of the {@linkplain AccessFlag access
     * flags} for this class, possibly empty}
     *
     * <p> If the underlying class is an array class:
     * <ul>
     * <li> its {@code PUBLIC}, {@code PRIVATE} and {@code PROTECTED}
     *      access flags are the same as those of its component type
     * <li> its {@code ABSTRACT} and {@code FINAL} flags are present
     * <li> its {@code INTERFACE} flag is absent, even when the
     *      component type is an interface
     * </ul>
     * If this {@code Class} object represents a primitive type or
     * void, the flags are {@code PUBLIC}, {@code ABSTRACT}, and
     * {@code FINAL}.
     * For {@code Class} objects representing void, primitive types, and
     * arrays, access flags are absent other than as specified above.
     *
     * @see #getModifiers()
     * @jvms 4.1 The ClassFile Structure
     * @jvms 4.7.6 The InnerClasses Attribute
     * @since 20
     */

    public Set<AccessFlag> accessFlags() {
        // Location.CLASS allows SUPER and AccessFlag.MODULE which
        // INNER_CLASS forbids. INNER_CLASS allows PRIVATE, PROTECTED,
        // and STATIC, which are not allowed on Location.CLASS.
        // Use getClassAccessFlagsRaw to expose SUPER status.
        var location = (isMemberClass() || isLocalClass() ||
                        isAnonymousClass() || isArray()) ?
            AccessFlag.Location.INNER_CLASS :
            AccessFlag.Location.CLASS;
        return AccessFlag.maskToAccessFlags((location == AccessFlag.Location.CLASS) ?
                                            getClassAccessFlagsRaw() :
                                            getModifiers(),
                                            location);
    }

    /**
     * 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 {@code Class} object represents
     *          a primitive type or void.
     * @since   1.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 class or
     * interface 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}.
     *
     * @throws SecurityException
     *         If a security manager, <i>s</i>, is present and any of the
     *         following conditions is met:
     *
     *         <ul>
     *
     *         <li> the caller's class loader is not the same as the
     *         class loader of the enclosing class and invocation of
     *         {@link SecurityManager#checkPermission
     *         s.checkPermission} method with
     *         {@code RuntimePermission("accessDeclaredMembers")}
     *         denies access to the methods within the enclosing class
     *
     *         <li> the caller's class loader is not the same as or an
     *         ancestor of the class loader for the enclosing class and
     *         invocation of {@link SecurityManager#checkPackageAccess
     *         s.checkPackageAccess()} denies access to the package
     *         of the enclosing class
     *
     *         </ul>
     * @since 1.5
     */

    @CallerSensitive
    public Method getEnclosingMethod() throws SecurityException {
        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]);

            // Perform access check
            final Class<?> enclosingCandidate = enclosingInfo.getEnclosingClass();
            @SuppressWarnings("removal")
            SecurityManager sm = System.getSecurityManager();
            if (sm != null) {
                enclosingCandidate.checkMemberAccess(sm, Member.DECLARED,
                                                     Reflection.getCallerClass(), true);
            }
            Method[] candidates = enclosingCandidate.privateGetDeclaredMethods(false);

            /*
             * 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.
             */

            ReflectionFactory fact = getReflectionFactory();
            for (Method m : candidates) {
                if (m.getName().equals(enclosingInfo.getName()) &&
                    arrayContentsEq(parameterClasses,
                                    fact.getExecutableSharedParameterTypes(m))) {
                    // finally, check return type
                    if (m.getReturnType().equals(returnType)) {
                        return fact.copyMethod(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 static final class EnclosingMethodInfo {
        private final Class<?> enclosingClass;
        private final String name;
        private final String descriptor;

        static void validate(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
                Class<?> enclosingClass = (Class<?>)enclosingInfo[0];
                assert(enclosingClass != null);

                // the immediately enclosing method or constructor's
                // name (can be null).
                String name = (String)enclosingInfo[1];

                // the immediately enclosing method or constructor's
                // descriptor (null iff name is).
                String descriptor = (String)enclosingInfo[2];
                assert((name != null && descriptor != null) || name == descriptor);
            } catch (ClassCastException cce) {
                throw new InternalError("Invalid type in enclosing method information", cce);
            }
        }

        EnclosingMethodInfo(Object[] enclosingInfo) {
            validate(enclosingInfo);
            this.enclosingClass = (Class<?>)enclosingInfo[0];
            this.name = (String)enclosingInfo[1];
            this.descriptor = (String)enclosingInfo[2];
        }

        boolean isPartial() {
            return enclosingClass == null || name == null || descriptor == null;
        }

        boolean isConstructor() { return !isPartial() && "".equals(name); }

        boolean isMethod() { return !isPartial() && !isConstructor() && !"".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;
     }

    /**
--> --------------------

--> maximum size reached

--> --------------------

Messung V0.5
C=95 H=94 G=94

¤ Dauer der Verarbeitung: 0.10 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge