emul/src/main/java/java/lang/Class.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Sat, 29 Sep 2012 06:47:05 +0200
branchjdk7-b147
changeset 56 d7a291b7808d
child 65 f99a92839285
permissions -rw-r--r--
3rd batch of classes
jaroslav@56
     1
/*
jaroslav@56
     2
 * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
jaroslav@56
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
jaroslav@56
     4
 *
jaroslav@56
     5
 * This code is free software; you can redistribute it and/or modify it
jaroslav@56
     6
 * under the terms of the GNU General Public License version 2 only, as
jaroslav@56
     7
 * published by the Free Software Foundation.  Oracle designates this
jaroslav@56
     8
 * particular file as subject to the "Classpath" exception as provided
jaroslav@56
     9
 * by Oracle in the LICENSE file that accompanied this code.
jaroslav@56
    10
 *
jaroslav@56
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
jaroslav@56
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
jaroslav@56
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
jaroslav@56
    14
 * version 2 for more details (a copy is included in the LICENSE file that
jaroslav@56
    15
 * accompanied this code).
jaroslav@56
    16
 *
jaroslav@56
    17
 * You should have received a copy of the GNU General Public License version
jaroslav@56
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
jaroslav@56
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
jaroslav@56
    20
 *
jaroslav@56
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
jaroslav@56
    22
 * or visit www.oracle.com if you need additional information or have any
jaroslav@56
    23
 * questions.
jaroslav@56
    24
 */
jaroslav@56
    25
jaroslav@56
    26
package java.lang;
jaroslav@56
    27
jaroslav@56
    28
import java.lang.reflect.Array;
jaroslav@56
    29
import java.lang.reflect.GenericArrayType;
jaroslav@56
    30
import java.lang.reflect.Member;
jaroslav@56
    31
import java.lang.reflect.Field;
jaroslav@56
    32
import java.lang.reflect.Method;
jaroslav@56
    33
import java.lang.reflect.Constructor;
jaroslav@56
    34
import java.lang.reflect.GenericDeclaration;
jaroslav@56
    35
import java.lang.reflect.Modifier;
jaroslav@56
    36
import java.lang.reflect.Type;
jaroslav@56
    37
import java.lang.reflect.TypeVariable;
jaroslav@56
    38
import java.lang.reflect.InvocationTargetException;
jaroslav@56
    39
import java.lang.ref.SoftReference;
jaroslav@56
    40
import java.io.InputStream;
jaroslav@56
    41
import java.io.ObjectStreamField;
jaroslav@56
    42
import java.security.AccessController;
jaroslav@56
    43
import java.security.PrivilegedAction;
jaroslav@56
    44
import java.util.ArrayList;
jaroslav@56
    45
import java.util.Arrays;
jaroslav@56
    46
import java.util.Collection;
jaroslav@56
    47
import java.util.HashSet;
jaroslav@56
    48
import java.util.Iterator;
jaroslav@56
    49
import java.util.List;
jaroslav@56
    50
import java.util.LinkedList;
jaroslav@56
    51
import java.util.LinkedHashSet;
jaroslav@56
    52
import java.util.Set;
jaroslav@56
    53
import java.util.Map;
jaroslav@56
    54
import java.util.HashMap;
jaroslav@56
    55
import sun.misc.Unsafe;
jaroslav@56
    56
import sun.reflect.ConstantPool;
jaroslav@56
    57
import sun.reflect.Reflection;
jaroslav@56
    58
import sun.reflect.ReflectionFactory;
jaroslav@56
    59
import sun.reflect.SignatureIterator;
jaroslav@56
    60
import sun.reflect.generics.factory.CoreReflectionFactory;
jaroslav@56
    61
import sun.reflect.generics.factory.GenericsFactory;
jaroslav@56
    62
import sun.reflect.generics.repository.ClassRepository;
jaroslav@56
    63
import sun.reflect.generics.repository.MethodRepository;
jaroslav@56
    64
import sun.reflect.generics.repository.ConstructorRepository;
jaroslav@56
    65
import sun.reflect.generics.scope.ClassScope;
jaroslav@56
    66
import sun.security.util.SecurityConstants;
jaroslav@56
    67
import java.lang.annotation.Annotation;
jaroslav@56
    68
import sun.reflect.annotation.*;
jaroslav@56
    69
jaroslav@56
    70
/**
jaroslav@56
    71
 * Instances of the class {@code Class} represent classes and
jaroslav@56
    72
 * interfaces in a running Java application.  An enum is a kind of
jaroslav@56
    73
 * class and an annotation is a kind of interface.  Every array also
jaroslav@56
    74
 * belongs to a class that is reflected as a {@code Class} object
jaroslav@56
    75
 * that is shared by all arrays with the same element type and number
jaroslav@56
    76
 * of dimensions.  The primitive Java types ({@code boolean},
jaroslav@56
    77
 * {@code byte}, {@code char}, {@code short},
jaroslav@56
    78
 * {@code int}, {@code long}, {@code float}, and
jaroslav@56
    79
 * {@code double}), and the keyword {@code void} are also
jaroslav@56
    80
 * represented as {@code Class} objects.
jaroslav@56
    81
 *
jaroslav@56
    82
 * <p> {@code Class} has no public constructor. Instead {@code Class}
jaroslav@56
    83
 * objects are constructed automatically by the Java Virtual Machine as classes
jaroslav@56
    84
 * are loaded and by calls to the {@code defineClass} method in the class
jaroslav@56
    85
 * loader.
jaroslav@56
    86
 *
jaroslav@56
    87
 * <p> The following example uses a {@code Class} object to print the
jaroslav@56
    88
 * class name of an object:
jaroslav@56
    89
 *
jaroslav@56
    90
 * <p> <blockquote><pre>
jaroslav@56
    91
 *     void printClassName(Object obj) {
jaroslav@56
    92
 *         System.out.println("The class of " + obj +
jaroslav@56
    93
 *                            " is " + obj.getClass().getName());
jaroslav@56
    94
 *     }
jaroslav@56
    95
 * </pre></blockquote>
jaroslav@56
    96
 *
jaroslav@56
    97
 * <p> It is also possible to get the {@code Class} object for a named
jaroslav@56
    98
 * type (or for void) using a class literal.  See Section 15.8.2 of
jaroslav@56
    99
 * <cite>The Java&trade; Language Specification</cite>.
jaroslav@56
   100
 * For example:
jaroslav@56
   101
 *
jaroslav@56
   102
 * <p> <blockquote>
jaroslav@56
   103
 *     {@code System.out.println("The name of class Foo is: "+Foo.class.getName());}
jaroslav@56
   104
 * </blockquote>
jaroslav@56
   105
 *
jaroslav@56
   106
 * @param <T> the type of the class modeled by this {@code Class}
jaroslav@56
   107
 * object.  For example, the type of {@code String.class} is {@code
jaroslav@56
   108
 * Class<String>}.  Use {@code Class<?>} if the class being modeled is
jaroslav@56
   109
 * unknown.
jaroslav@56
   110
 *
jaroslav@56
   111
 * @author  unascribed
jaroslav@56
   112
 * @see     java.lang.ClassLoader#defineClass(byte[], int, int)
jaroslav@56
   113
 * @since   JDK1.0
jaroslav@56
   114
 */
jaroslav@56
   115
public final
jaroslav@56
   116
    class Class<T> implements java.io.Serializable,
jaroslav@56
   117
                              java.lang.reflect.GenericDeclaration,
jaroslav@56
   118
                              java.lang.reflect.Type,
jaroslav@56
   119
                              java.lang.reflect.AnnotatedElement {
jaroslav@56
   120
    private static final int ANNOTATION= 0x00002000;
jaroslav@56
   121
    private static final int ENUM      = 0x00004000;
jaroslav@56
   122
    private static final int SYNTHETIC = 0x00001000;
jaroslav@56
   123
jaroslav@56
   124
    private static native void registerNatives();
jaroslav@56
   125
    static {
jaroslav@56
   126
        registerNatives();
jaroslav@56
   127
    }
jaroslav@56
   128
jaroslav@56
   129
    /*
jaroslav@56
   130
     * Constructor. Only the Java Virtual Machine creates Class
jaroslav@56
   131
     * objects.
jaroslav@56
   132
     */
jaroslav@56
   133
    private Class() {}
jaroslav@56
   134
jaroslav@56
   135
jaroslav@56
   136
    /**
jaroslav@56
   137
     * Converts the object to a string. The string representation is the
jaroslav@56
   138
     * string "class" or "interface", followed by a space, and then by the
jaroslav@56
   139
     * fully qualified name of the class in the format returned by
jaroslav@56
   140
     * {@code getName}.  If this {@code Class} object represents a
jaroslav@56
   141
     * primitive type, this method returns the name of the primitive type.  If
jaroslav@56
   142
     * this {@code Class} object represents void this method returns
jaroslav@56
   143
     * "void".
jaroslav@56
   144
     *
jaroslav@56
   145
     * @return a string representation of this class object.
jaroslav@56
   146
     */
jaroslav@56
   147
    public String toString() {
jaroslav@56
   148
        return (isInterface() ? "interface " : (isPrimitive() ? "" : "class "))
jaroslav@56
   149
            + getName();
jaroslav@56
   150
    }
jaroslav@56
   151
jaroslav@56
   152
jaroslav@56
   153
    /**
jaroslav@56
   154
     * Returns the {@code Class} object associated with the class or
jaroslav@56
   155
     * interface with the given string name.  Invoking this method is
jaroslav@56
   156
     * equivalent to:
jaroslav@56
   157
     *
jaroslav@56
   158
     * <blockquote>
jaroslav@56
   159
     *  {@code Class.forName(className, true, currentLoader)}
jaroslav@56
   160
     * </blockquote>
jaroslav@56
   161
     *
jaroslav@56
   162
     * where {@code currentLoader} denotes the defining class loader of
jaroslav@56
   163
     * the current class.
jaroslav@56
   164
     *
jaroslav@56
   165
     * <p> For example, the following code fragment returns the
jaroslav@56
   166
     * runtime {@code Class} descriptor for the class named
jaroslav@56
   167
     * {@code java.lang.Thread}:
jaroslav@56
   168
     *
jaroslav@56
   169
     * <blockquote>
jaroslav@56
   170
     *   {@code Class t = Class.forName("java.lang.Thread")}
jaroslav@56
   171
     * </blockquote>
jaroslav@56
   172
     * <p>
jaroslav@56
   173
     * A call to {@code forName("X")} causes the class named
jaroslav@56
   174
     * {@code X} to be initialized.
jaroslav@56
   175
     *
jaroslav@56
   176
     * @param      className   the fully qualified name of the desired class.
jaroslav@56
   177
     * @return     the {@code Class} object for the class with the
jaroslav@56
   178
     *             specified name.
jaroslav@56
   179
     * @exception LinkageError if the linkage fails
jaroslav@56
   180
     * @exception ExceptionInInitializerError if the initialization provoked
jaroslav@56
   181
     *            by this method fails
jaroslav@56
   182
     * @exception ClassNotFoundException if the class cannot be located
jaroslav@56
   183
     */
jaroslav@56
   184
    public static Class<?> forName(String className)
jaroslav@56
   185
                throws ClassNotFoundException {
jaroslav@56
   186
        return forName0(className, true, ClassLoader.getCallerClassLoader());
jaroslav@56
   187
    }
jaroslav@56
   188
jaroslav@56
   189
jaroslav@56
   190
    /**
jaroslav@56
   191
     * Returns the {@code Class} object associated with the class or
jaroslav@56
   192
     * interface with the given string name, using the given class loader.
jaroslav@56
   193
     * Given the fully qualified name for a class or interface (in the same
jaroslav@56
   194
     * format returned by {@code getName}) this method attempts to
jaroslav@56
   195
     * locate, load, and link the class or interface.  The specified class
jaroslav@56
   196
     * loader is used to load the class or interface.  If the parameter
jaroslav@56
   197
     * {@code loader} is null, the class is loaded through the bootstrap
jaroslav@56
   198
     * class loader.  The class is initialized only if the
jaroslav@56
   199
     * {@code initialize} parameter is {@code true} and if it has
jaroslav@56
   200
     * not been initialized earlier.
jaroslav@56
   201
     *
jaroslav@56
   202
     * <p> If {@code name} denotes a primitive type or void, an attempt
jaroslav@56
   203
     * will be made to locate a user-defined class in the unnamed package whose
jaroslav@56
   204
     * name is {@code name}. Therefore, this method cannot be used to
jaroslav@56
   205
     * obtain any of the {@code Class} objects representing primitive
jaroslav@56
   206
     * types or void.
jaroslav@56
   207
     *
jaroslav@56
   208
     * <p> If {@code name} denotes an array class, the component type of
jaroslav@56
   209
     * the array class is loaded but not initialized.
jaroslav@56
   210
     *
jaroslav@56
   211
     * <p> For example, in an instance method the expression:
jaroslav@56
   212
     *
jaroslav@56
   213
     * <blockquote>
jaroslav@56
   214
     *  {@code Class.forName("Foo")}
jaroslav@56
   215
     * </blockquote>
jaroslav@56
   216
     *
jaroslav@56
   217
     * is equivalent to:
jaroslav@56
   218
     *
jaroslav@56
   219
     * <blockquote>
jaroslav@56
   220
     *  {@code Class.forName("Foo", true, this.getClass().getClassLoader())}
jaroslav@56
   221
     * </blockquote>
jaroslav@56
   222
     *
jaroslav@56
   223
     * Note that this method throws errors related to loading, linking or
jaroslav@56
   224
     * initializing as specified in Sections 12.2, 12.3 and 12.4 of <em>The
jaroslav@56
   225
     * Java Language Specification</em>.
jaroslav@56
   226
     * Note that this method does not check whether the requested class
jaroslav@56
   227
     * is accessible to its caller.
jaroslav@56
   228
     *
jaroslav@56
   229
     * <p> If the {@code loader} is {@code null}, and a security
jaroslav@56
   230
     * manager is present, and the caller's class loader is not null, then this
jaroslav@56
   231
     * method calls the security manager's {@code checkPermission} method
jaroslav@56
   232
     * with a {@code RuntimePermission("getClassLoader")} permission to
jaroslav@56
   233
     * ensure it's ok to access the bootstrap class loader.
jaroslav@56
   234
     *
jaroslav@56
   235
     * @param name       fully qualified name of the desired class
jaroslav@56
   236
     * @param initialize whether the class must be initialized
jaroslav@56
   237
     * @param loader     class loader from which the class must be loaded
jaroslav@56
   238
     * @return           class object representing the desired class
jaroslav@56
   239
     *
jaroslav@56
   240
     * @exception LinkageError if the linkage fails
jaroslav@56
   241
     * @exception ExceptionInInitializerError if the initialization provoked
jaroslav@56
   242
     *            by this method fails
jaroslav@56
   243
     * @exception ClassNotFoundException if the class cannot be located by
jaroslav@56
   244
     *            the specified class loader
jaroslav@56
   245
     *
jaroslav@56
   246
     * @see       java.lang.Class#forName(String)
jaroslav@56
   247
     * @see       java.lang.ClassLoader
jaroslav@56
   248
     * @since     1.2
jaroslav@56
   249
     */
jaroslav@56
   250
    public static Class<?> forName(String name, boolean initialize,
jaroslav@56
   251
                                   ClassLoader loader)
jaroslav@56
   252
        throws ClassNotFoundException
jaroslav@56
   253
    {
jaroslav@56
   254
        if (loader == null) {
jaroslav@56
   255
            SecurityManager sm = System.getSecurityManager();
jaroslav@56
   256
            if (sm != null) {
jaroslav@56
   257
                ClassLoader ccl = ClassLoader.getCallerClassLoader();
jaroslav@56
   258
                if (ccl != null) {
jaroslav@56
   259
                    sm.checkPermission(
jaroslav@56
   260
                        SecurityConstants.GET_CLASSLOADER_PERMISSION);
jaroslav@56
   261
                }
jaroslav@56
   262
            }
jaroslav@56
   263
        }
jaroslav@56
   264
        return forName0(name, initialize, loader);
jaroslav@56
   265
    }
jaroslav@56
   266
jaroslav@56
   267
    /** Called after security checks have been made. */
jaroslav@56
   268
    private static native Class<?> forName0(String name, boolean initialize,
jaroslav@56
   269
                                            ClassLoader loader)
jaroslav@56
   270
        throws ClassNotFoundException;
jaroslav@56
   271
jaroslav@56
   272
    /**
jaroslav@56
   273
     * Creates a new instance of the class represented by this {@code Class}
jaroslav@56
   274
     * object.  The class is instantiated as if by a {@code new}
jaroslav@56
   275
     * expression with an empty argument list.  The class is initialized if it
jaroslav@56
   276
     * has not already been initialized.
jaroslav@56
   277
     *
jaroslav@56
   278
     * <p>Note that this method propagates any exception thrown by the
jaroslav@56
   279
     * nullary constructor, including a checked exception.  Use of
jaroslav@56
   280
     * this method effectively bypasses the compile-time exception
jaroslav@56
   281
     * checking that would otherwise be performed by the compiler.
jaroslav@56
   282
     * The {@link
jaroslav@56
   283
     * java.lang.reflect.Constructor#newInstance(java.lang.Object...)
jaroslav@56
   284
     * Constructor.newInstance} method avoids this problem by wrapping
jaroslav@56
   285
     * any exception thrown by the constructor in a (checked) {@link
jaroslav@56
   286
     * java.lang.reflect.InvocationTargetException}.
jaroslav@56
   287
     *
jaroslav@56
   288
     * @return     a newly allocated instance of the class represented by this
jaroslav@56
   289
     *             object.
jaroslav@56
   290
     * @exception  IllegalAccessException  if the class or its nullary
jaroslav@56
   291
     *               constructor is not accessible.
jaroslav@56
   292
     * @exception  InstantiationException
jaroslav@56
   293
     *               if this {@code Class} represents an abstract class,
jaroslav@56
   294
     *               an interface, an array class, a primitive type, or void;
jaroslav@56
   295
     *               or if the class has no nullary constructor;
jaroslav@56
   296
     *               or if the instantiation fails for some other reason.
jaroslav@56
   297
     * @exception  ExceptionInInitializerError if the initialization
jaroslav@56
   298
     *               provoked by this method fails.
jaroslav@56
   299
     * @exception  SecurityException
jaroslav@56
   300
     *             If a security manager, <i>s</i>, is present and any of the
jaroslav@56
   301
     *             following conditions is met:
jaroslav@56
   302
     *
jaroslav@56
   303
     *             <ul>
jaroslav@56
   304
     *
jaroslav@56
   305
     *             <li> invocation of
jaroslav@56
   306
     *             {@link SecurityManager#checkMemberAccess
jaroslav@56
   307
     *             s.checkMemberAccess(this, Member.PUBLIC)} denies
jaroslav@56
   308
     *             creation of new instances of this class
jaroslav@56
   309
     *
jaroslav@56
   310
     *             <li> the caller's class loader is not the same as or an
jaroslav@56
   311
     *             ancestor of the class loader for the current class and
jaroslav@56
   312
     *             invocation of {@link SecurityManager#checkPackageAccess
jaroslav@56
   313
     *             s.checkPackageAccess()} denies access to the package
jaroslav@56
   314
     *             of this class
jaroslav@56
   315
     *
jaroslav@56
   316
     *             </ul>
jaroslav@56
   317
     *
jaroslav@56
   318
     */
jaroslav@56
   319
    public T newInstance()
jaroslav@56
   320
        throws InstantiationException, IllegalAccessException
jaroslav@56
   321
    {
jaroslav@56
   322
        if (System.getSecurityManager() != null) {
jaroslav@56
   323
            checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
jaroslav@56
   324
        }
jaroslav@56
   325
        return newInstance0();
jaroslav@56
   326
    }
jaroslav@56
   327
jaroslav@56
   328
    private T newInstance0()
jaroslav@56
   329
        throws InstantiationException, IllegalAccessException
jaroslav@56
   330
    {
jaroslav@56
   331
        // NOTE: the following code may not be strictly correct under
jaroslav@56
   332
        // the current Java memory model.
jaroslav@56
   333
jaroslav@56
   334
        // Constructor lookup
jaroslav@56
   335
        if (cachedConstructor == null) {
jaroslav@56
   336
            if (this == Class.class) {
jaroslav@56
   337
                throw new IllegalAccessException(
jaroslav@56
   338
                    "Can not call newInstance() on the Class for java.lang.Class"
jaroslav@56
   339
                );
jaroslav@56
   340
            }
jaroslav@56
   341
            try {
jaroslav@56
   342
                Class<?>[] empty = {};
jaroslav@56
   343
                final Constructor<T> c = getConstructor0(empty, Member.DECLARED);
jaroslav@56
   344
                // Disable accessibility checks on the constructor
jaroslav@56
   345
                // since we have to do the security check here anyway
jaroslav@56
   346
                // (the stack depth is wrong for the Constructor's
jaroslav@56
   347
                // security check to work)
jaroslav@56
   348
                java.security.AccessController.doPrivileged(
jaroslav@56
   349
                    new java.security.PrivilegedAction<Void>() {
jaroslav@56
   350
                        public Void run() {
jaroslav@56
   351
                                c.setAccessible(true);
jaroslav@56
   352
                                return null;
jaroslav@56
   353
                            }
jaroslav@56
   354
                        });
jaroslav@56
   355
                cachedConstructor = c;
jaroslav@56
   356
            } catch (NoSuchMethodException e) {
jaroslav@56
   357
                throw new InstantiationException(getName());
jaroslav@56
   358
            }
jaroslav@56
   359
        }
jaroslav@56
   360
        Constructor<T> tmpConstructor = cachedConstructor;
jaroslav@56
   361
        // Security check (same as in java.lang.reflect.Constructor)
jaroslav@56
   362
        int modifiers = tmpConstructor.getModifiers();
jaroslav@56
   363
        if (!Reflection.quickCheckMemberAccess(this, modifiers)) {
jaroslav@56
   364
            Class<?> caller = Reflection.getCallerClass(3);
jaroslav@56
   365
            if (newInstanceCallerCache != caller) {
jaroslav@56
   366
                Reflection.ensureMemberAccess(caller, this, null, modifiers);
jaroslav@56
   367
                newInstanceCallerCache = caller;
jaroslav@56
   368
            }
jaroslav@56
   369
        }
jaroslav@56
   370
        // Run constructor
jaroslav@56
   371
        try {
jaroslav@56
   372
            return tmpConstructor.newInstance((Object[])null);
jaroslav@56
   373
        } catch (InvocationTargetException e) {
jaroslav@56
   374
            Unsafe.getUnsafe().throwException(e.getTargetException());
jaroslav@56
   375
            // Not reached
jaroslav@56
   376
            return null;
jaroslav@56
   377
        }
jaroslav@56
   378
    }
jaroslav@56
   379
    private volatile transient Constructor<T> cachedConstructor;
jaroslav@56
   380
    private volatile transient Class<?>       newInstanceCallerCache;
jaroslav@56
   381
jaroslav@56
   382
jaroslav@56
   383
    /**
jaroslav@56
   384
     * Determines if the specified {@code Object} is assignment-compatible
jaroslav@56
   385
     * with the object represented by this {@code Class}.  This method is
jaroslav@56
   386
     * the dynamic equivalent of the Java language {@code instanceof}
jaroslav@56
   387
     * operator. The method returns {@code true} if the specified
jaroslav@56
   388
     * {@code Object} argument is non-null and can be cast to the
jaroslav@56
   389
     * reference type represented by this {@code Class} object without
jaroslav@56
   390
     * raising a {@code ClassCastException.} It returns {@code false}
jaroslav@56
   391
     * otherwise.
jaroslav@56
   392
     *
jaroslav@56
   393
     * <p> Specifically, if this {@code Class} object represents a
jaroslav@56
   394
     * declared class, this method returns {@code true} if the specified
jaroslav@56
   395
     * {@code Object} argument is an instance of the represented class (or
jaroslav@56
   396
     * of any of its subclasses); it returns {@code false} otherwise. If
jaroslav@56
   397
     * this {@code Class} object represents an array class, this method
jaroslav@56
   398
     * returns {@code true} if the specified {@code Object} argument
jaroslav@56
   399
     * can be converted to an object of the array class by an identity
jaroslav@56
   400
     * conversion or by a widening reference conversion; it returns
jaroslav@56
   401
     * {@code false} otherwise. If this {@code Class} object
jaroslav@56
   402
     * represents an interface, this method returns {@code true} if the
jaroslav@56
   403
     * class or any superclass of the specified {@code Object} argument
jaroslav@56
   404
     * implements this interface; it returns {@code false} otherwise. If
jaroslav@56
   405
     * this {@code Class} object represents a primitive type, this method
jaroslav@56
   406
     * returns {@code false}.
jaroslav@56
   407
     *
jaroslav@56
   408
     * @param   obj the object to check
jaroslav@56
   409
     * @return  true if {@code obj} is an instance of this class
jaroslav@56
   410
     *
jaroslav@56
   411
     * @since JDK1.1
jaroslav@56
   412
     */
jaroslav@56
   413
    public native boolean isInstance(Object obj);
jaroslav@56
   414
jaroslav@56
   415
jaroslav@56
   416
    /**
jaroslav@56
   417
     * Determines if the class or interface represented by this
jaroslav@56
   418
     * {@code Class} object is either the same as, or is a superclass or
jaroslav@56
   419
     * superinterface of, the class or interface represented by the specified
jaroslav@56
   420
     * {@code Class} parameter. It returns {@code true} if so;
jaroslav@56
   421
     * otherwise it returns {@code false}. If this {@code Class}
jaroslav@56
   422
     * object represents a primitive type, this method returns
jaroslav@56
   423
     * {@code true} if the specified {@code Class} parameter is
jaroslav@56
   424
     * exactly this {@code Class} object; otherwise it returns
jaroslav@56
   425
     * {@code false}.
jaroslav@56
   426
     *
jaroslav@56
   427
     * <p> Specifically, this method tests whether the type represented by the
jaroslav@56
   428
     * specified {@code Class} parameter can be converted to the type
jaroslav@56
   429
     * represented by this {@code Class} object via an identity conversion
jaroslav@56
   430
     * or via a widening reference conversion. See <em>The Java Language
jaroslav@56
   431
     * Specification</em>, sections 5.1.1 and 5.1.4 , for details.
jaroslav@56
   432
     *
jaroslav@56
   433
     * @param cls the {@code Class} object to be checked
jaroslav@56
   434
     * @return the {@code boolean} value indicating whether objects of the
jaroslav@56
   435
     * type {@code cls} can be assigned to objects of this class
jaroslav@56
   436
     * @exception NullPointerException if the specified Class parameter is
jaroslav@56
   437
     *            null.
jaroslav@56
   438
     * @since JDK1.1
jaroslav@56
   439
     */
jaroslav@56
   440
    public native boolean isAssignableFrom(Class<?> cls);
jaroslav@56
   441
jaroslav@56
   442
jaroslav@56
   443
    /**
jaroslav@56
   444
     * Determines if the specified {@code Class} object represents an
jaroslav@56
   445
     * interface type.
jaroslav@56
   446
     *
jaroslav@56
   447
     * @return  {@code true} if this object represents an interface;
jaroslav@56
   448
     *          {@code false} otherwise.
jaroslav@56
   449
     */
jaroslav@56
   450
    public native boolean isInterface();
jaroslav@56
   451
jaroslav@56
   452
jaroslav@56
   453
    /**
jaroslav@56
   454
     * Determines if this {@code Class} object represents an array class.
jaroslav@56
   455
     *
jaroslav@56
   456
     * @return  {@code true} if this object represents an array class;
jaroslav@56
   457
     *          {@code false} otherwise.
jaroslav@56
   458
     * @since   JDK1.1
jaroslav@56
   459
     */
jaroslav@56
   460
    public native boolean isArray();
jaroslav@56
   461
jaroslav@56
   462
jaroslav@56
   463
    /**
jaroslav@56
   464
     * Determines if the specified {@code Class} object represents a
jaroslav@56
   465
     * primitive type.
jaroslav@56
   466
     *
jaroslav@56
   467
     * <p> There are nine predefined {@code Class} objects to represent
jaroslav@56
   468
     * the eight primitive types and void.  These are created by the Java
jaroslav@56
   469
     * Virtual Machine, and have the same names as the primitive types that
jaroslav@56
   470
     * they represent, namely {@code boolean}, {@code byte},
jaroslav@56
   471
     * {@code char}, {@code short}, {@code int},
jaroslav@56
   472
     * {@code long}, {@code float}, and {@code double}.
jaroslav@56
   473
     *
jaroslav@56
   474
     * <p> These objects may only be accessed via the following public static
jaroslav@56
   475
     * final variables, and are the only {@code Class} objects for which
jaroslav@56
   476
     * this method returns {@code true}.
jaroslav@56
   477
     *
jaroslav@56
   478
     * @return true if and only if this class represents a primitive type
jaroslav@56
   479
     *
jaroslav@56
   480
     * @see     java.lang.Boolean#TYPE
jaroslav@56
   481
     * @see     java.lang.Character#TYPE
jaroslav@56
   482
     * @see     java.lang.Byte#TYPE
jaroslav@56
   483
     * @see     java.lang.Short#TYPE
jaroslav@56
   484
     * @see     java.lang.Integer#TYPE
jaroslav@56
   485
     * @see     java.lang.Long#TYPE
jaroslav@56
   486
     * @see     java.lang.Float#TYPE
jaroslav@56
   487
     * @see     java.lang.Double#TYPE
jaroslav@56
   488
     * @see     java.lang.Void#TYPE
jaroslav@56
   489
     * @since JDK1.1
jaroslav@56
   490
     */
jaroslav@56
   491
    public native boolean isPrimitive();
jaroslav@56
   492
jaroslav@56
   493
    /**
jaroslav@56
   494
     * Returns true if this {@code Class} object represents an annotation
jaroslav@56
   495
     * type.  Note that if this method returns true, {@link #isInterface()}
jaroslav@56
   496
     * would also return true, as all annotation types are also interfaces.
jaroslav@56
   497
     *
jaroslav@56
   498
     * @return {@code true} if this class object represents an annotation
jaroslav@56
   499
     *      type; {@code false} otherwise
jaroslav@56
   500
     * @since 1.5
jaroslav@56
   501
     */
jaroslav@56
   502
    public boolean isAnnotation() {
jaroslav@56
   503
        return (getModifiers() & ANNOTATION) != 0;
jaroslav@56
   504
    }
jaroslav@56
   505
jaroslav@56
   506
    /**
jaroslav@56
   507
     * Returns {@code true} if this class is a synthetic class;
jaroslav@56
   508
     * returns {@code false} otherwise.
jaroslav@56
   509
     * @return {@code true} if and only if this class is a synthetic class as
jaroslav@56
   510
     *         defined by the Java Language Specification.
jaroslav@56
   511
     * @since 1.5
jaroslav@56
   512
     */
jaroslav@56
   513
    public boolean isSynthetic() {
jaroslav@56
   514
        return (getModifiers() & SYNTHETIC) != 0;
jaroslav@56
   515
    }
jaroslav@56
   516
jaroslav@56
   517
    /**
jaroslav@56
   518
     * Returns the  name of the entity (class, interface, array class,
jaroslav@56
   519
     * primitive type, or void) represented by this {@code Class} object,
jaroslav@56
   520
     * as a {@code String}.
jaroslav@56
   521
     *
jaroslav@56
   522
     * <p> If this class object represents a reference type that is not an
jaroslav@56
   523
     * array type then the binary name of the class is returned, as specified
jaroslav@56
   524
     * by
jaroslav@56
   525
     * <cite>The Java&trade; Language Specification</cite>.
jaroslav@56
   526
     *
jaroslav@56
   527
     * <p> If this class object represents a primitive type or void, then the
jaroslav@56
   528
     * name returned is a {@code String} equal to the Java language
jaroslav@56
   529
     * keyword corresponding to the primitive type or void.
jaroslav@56
   530
     *
jaroslav@56
   531
     * <p> If this class object represents a class of arrays, then the internal
jaroslav@56
   532
     * form of the name consists of the name of the element type preceded by
jaroslav@56
   533
     * one or more '{@code [}' characters representing the depth of the array
jaroslav@56
   534
     * nesting.  The encoding of element type names is as follows:
jaroslav@56
   535
     *
jaroslav@56
   536
     * <blockquote><table summary="Element types and encodings">
jaroslav@56
   537
     * <tr><th> Element Type <th> &nbsp;&nbsp;&nbsp; <th> Encoding
jaroslav@56
   538
     * <tr><td> boolean      <td> &nbsp;&nbsp;&nbsp; <td align=center> Z
jaroslav@56
   539
     * <tr><td> byte         <td> &nbsp;&nbsp;&nbsp; <td align=center> B
jaroslav@56
   540
     * <tr><td> char         <td> &nbsp;&nbsp;&nbsp; <td align=center> C
jaroslav@56
   541
     * <tr><td> class or interface
jaroslav@56
   542
     *                       <td> &nbsp;&nbsp;&nbsp; <td align=center> L<i>classname</i>;
jaroslav@56
   543
     * <tr><td> double       <td> &nbsp;&nbsp;&nbsp; <td align=center> D
jaroslav@56
   544
     * <tr><td> float        <td> &nbsp;&nbsp;&nbsp; <td align=center> F
jaroslav@56
   545
     * <tr><td> int          <td> &nbsp;&nbsp;&nbsp; <td align=center> I
jaroslav@56
   546
     * <tr><td> long         <td> &nbsp;&nbsp;&nbsp; <td align=center> J
jaroslav@56
   547
     * <tr><td> short        <td> &nbsp;&nbsp;&nbsp; <td align=center> S
jaroslav@56
   548
     * </table></blockquote>
jaroslav@56
   549
     *
jaroslav@56
   550
     * <p> The class or interface name <i>classname</i> is the binary name of
jaroslav@56
   551
     * the class specified above.
jaroslav@56
   552
     *
jaroslav@56
   553
     * <p> Examples:
jaroslav@56
   554
     * <blockquote><pre>
jaroslav@56
   555
     * String.class.getName()
jaroslav@56
   556
     *     returns "java.lang.String"
jaroslav@56
   557
     * byte.class.getName()
jaroslav@56
   558
     *     returns "byte"
jaroslav@56
   559
     * (new Object[3]).getClass().getName()
jaroslav@56
   560
     *     returns "[Ljava.lang.Object;"
jaroslav@56
   561
     * (new int[3][4][5][6][7][8][9]).getClass().getName()
jaroslav@56
   562
     *     returns "[[[[[[[I"
jaroslav@56
   563
     * </pre></blockquote>
jaroslav@56
   564
     *
jaroslav@56
   565
     * @return  the name of the class or interface
jaroslav@56
   566
     *          represented by this object.
jaroslav@56
   567
     */
jaroslav@56
   568
    public String getName() {
jaroslav@56
   569
        String name = this.name;
jaroslav@56
   570
        if (name == null)
jaroslav@56
   571
            this.name = name = getName0();
jaroslav@56
   572
        return name;
jaroslav@56
   573
    }
jaroslav@56
   574
jaroslav@56
   575
    // cache the name to reduce the number of calls into the VM
jaroslav@56
   576
    private transient String name;
jaroslav@56
   577
    private native String getName0();
jaroslav@56
   578
jaroslav@56
   579
    /**
jaroslav@56
   580
     * Returns the class loader for the class.  Some implementations may use
jaroslav@56
   581
     * null to represent the bootstrap class loader. This method will return
jaroslav@56
   582
     * null in such implementations if this class was loaded by the bootstrap
jaroslav@56
   583
     * class loader.
jaroslav@56
   584
     *
jaroslav@56
   585
     * <p> If a security manager is present, and the caller's class loader is
jaroslav@56
   586
     * not null and the caller's class loader is not the same as or an ancestor of
jaroslav@56
   587
     * the class loader for the class whose class loader is requested, then
jaroslav@56
   588
     * this method calls the security manager's {@code checkPermission}
jaroslav@56
   589
     * method with a {@code RuntimePermission("getClassLoader")}
jaroslav@56
   590
     * permission to ensure it's ok to access the class loader for the class.
jaroslav@56
   591
     *
jaroslav@56
   592
     * <p>If this object
jaroslav@56
   593
     * represents a primitive type or void, null is returned.
jaroslav@56
   594
     *
jaroslav@56
   595
     * @return  the class loader that loaded the class or interface
jaroslav@56
   596
     *          represented by this object.
jaroslav@56
   597
     * @throws SecurityException
jaroslav@56
   598
     *    if a security manager exists and its
jaroslav@56
   599
     *    {@code checkPermission} method denies
jaroslav@56
   600
     *    access to the class loader for the class.
jaroslav@56
   601
     * @see java.lang.ClassLoader
jaroslav@56
   602
     * @see SecurityManager#checkPermission
jaroslav@56
   603
     * @see java.lang.RuntimePermission
jaroslav@56
   604
     */
jaroslav@56
   605
    public ClassLoader getClassLoader() {
jaroslav@56
   606
        ClassLoader cl = getClassLoader0();
jaroslav@56
   607
        if (cl == null)
jaroslav@56
   608
            return null;
jaroslav@56
   609
        SecurityManager sm = System.getSecurityManager();
jaroslav@56
   610
        if (sm != null) {
jaroslav@56
   611
            ClassLoader ccl = ClassLoader.getCallerClassLoader();
jaroslav@56
   612
            if (ccl != null && ccl != cl && !cl.isAncestor(ccl)) {
jaroslav@56
   613
                sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
jaroslav@56
   614
            }
jaroslav@56
   615
        }
jaroslav@56
   616
        return cl;
jaroslav@56
   617
    }
jaroslav@56
   618
jaroslav@56
   619
    // Package-private to allow ClassLoader access
jaroslav@56
   620
    native ClassLoader getClassLoader0();
jaroslav@56
   621
jaroslav@56
   622
jaroslav@56
   623
    /**
jaroslav@56
   624
     * Returns an array of {@code TypeVariable} objects that represent the
jaroslav@56
   625
     * type variables declared by the generic declaration represented by this
jaroslav@56
   626
     * {@code GenericDeclaration} object, in declaration order.  Returns an
jaroslav@56
   627
     * array of length 0 if the underlying generic declaration declares no type
jaroslav@56
   628
     * variables.
jaroslav@56
   629
     *
jaroslav@56
   630
     * @return an array of {@code TypeVariable} objects that represent
jaroslav@56
   631
     *     the type variables declared by this generic declaration
jaroslav@56
   632
     * @throws java.lang.reflect.GenericSignatureFormatError if the generic
jaroslav@56
   633
     *     signature of this generic declaration does not conform to
jaroslav@56
   634
     *     the format specified in
jaroslav@56
   635
     *     <cite>The Java&trade; Virtual Machine Specification</cite>
jaroslav@56
   636
     * @since 1.5
jaroslav@56
   637
     */
jaroslav@56
   638
    public TypeVariable<Class<T>>[] getTypeParameters() {
jaroslav@56
   639
        if (getGenericSignature() != null)
jaroslav@56
   640
            return (TypeVariable<Class<T>>[])getGenericInfo().getTypeParameters();
jaroslav@56
   641
        else
jaroslav@56
   642
            return (TypeVariable<Class<T>>[])new TypeVariable<?>[0];
jaroslav@56
   643
    }
jaroslav@56
   644
jaroslav@56
   645
jaroslav@56
   646
    /**
jaroslav@56
   647
     * Returns the {@code Class} representing the superclass of the entity
jaroslav@56
   648
     * (class, interface, primitive type or void) represented by this
jaroslav@56
   649
     * {@code Class}.  If this {@code Class} represents either the
jaroslav@56
   650
     * {@code Object} class, an interface, a primitive type, or void, then
jaroslav@56
   651
     * null is returned.  If this object represents an array class then the
jaroslav@56
   652
     * {@code Class} object representing the {@code Object} class is
jaroslav@56
   653
     * returned.
jaroslav@56
   654
     *
jaroslav@56
   655
     * @return the superclass of the class represented by this object.
jaroslav@56
   656
     */
jaroslav@56
   657
    public native Class<? super T> getSuperclass();
jaroslav@56
   658
jaroslav@56
   659
jaroslav@56
   660
    /**
jaroslav@56
   661
     * Returns the {@code Type} representing the direct superclass of
jaroslav@56
   662
     * the entity (class, interface, primitive type or void) represented by
jaroslav@56
   663
     * this {@code Class}.
jaroslav@56
   664
     *
jaroslav@56
   665
     * <p>If the superclass is a parameterized type, the {@code Type}
jaroslav@56
   666
     * object returned must accurately reflect the actual type
jaroslav@56
   667
     * parameters used in the source code. The parameterized type
jaroslav@56
   668
     * representing the superclass is created if it had not been
jaroslav@56
   669
     * created before. See the declaration of {@link
jaroslav@56
   670
     * java.lang.reflect.ParameterizedType ParameterizedType} for the
jaroslav@56
   671
     * semantics of the creation process for parameterized types.  If
jaroslav@56
   672
     * this {@code Class} represents either the {@code Object}
jaroslav@56
   673
     * class, an interface, a primitive type, or void, then null is
jaroslav@56
   674
     * returned.  If this object represents an array class then the
jaroslav@56
   675
     * {@code Class} object representing the {@code Object} class is
jaroslav@56
   676
     * returned.
jaroslav@56
   677
     *
jaroslav@56
   678
     * @throws java.lang.reflect.GenericSignatureFormatError if the generic
jaroslav@56
   679
     *     class signature does not conform to the format specified in
jaroslav@56
   680
     *     <cite>The Java&trade; Virtual Machine Specification</cite>
jaroslav@56
   681
     * @throws TypeNotPresentException if the generic superclass
jaroslav@56
   682
     *     refers to a non-existent type declaration
jaroslav@56
   683
     * @throws java.lang.reflect.MalformedParameterizedTypeException if the
jaroslav@56
   684
     *     generic superclass refers to a parameterized type that cannot be
jaroslav@56
   685
     *     instantiated  for any reason
jaroslav@56
   686
     * @return the superclass of the class represented by this object
jaroslav@56
   687
     * @since 1.5
jaroslav@56
   688
     */
jaroslav@56
   689
    public Type getGenericSuperclass() {
jaroslav@56
   690
        if (getGenericSignature() != null) {
jaroslav@56
   691
            // Historical irregularity:
jaroslav@56
   692
            // Generic signature marks interfaces with superclass = Object
jaroslav@56
   693
            // but this API returns null for interfaces
jaroslav@56
   694
            if (isInterface())
jaroslav@56
   695
                return null;
jaroslav@56
   696
            return getGenericInfo().getSuperclass();
jaroslav@56
   697
        } else
jaroslav@56
   698
            return getSuperclass();
jaroslav@56
   699
    }
jaroslav@56
   700
jaroslav@56
   701
    /**
jaroslav@56
   702
     * Gets the package for this class.  The class loader of this class is used
jaroslav@56
   703
     * to find the package.  If the class was loaded by the bootstrap class
jaroslav@56
   704
     * loader the set of packages loaded from CLASSPATH is searched to find the
jaroslav@56
   705
     * package of the class. Null is returned if no package object was created
jaroslav@56
   706
     * by the class loader of this class.
jaroslav@56
   707
     *
jaroslav@56
   708
     * <p> Packages have attributes for versions and specifications only if the
jaroslav@56
   709
     * information was defined in the manifests that accompany the classes, and
jaroslav@56
   710
     * if the class loader created the package instance with the attributes
jaroslav@56
   711
     * from the manifest.
jaroslav@56
   712
     *
jaroslav@56
   713
     * @return the package of the class, or null if no package
jaroslav@56
   714
     *         information is available from the archive or codebase.
jaroslav@56
   715
     */
jaroslav@56
   716
    public Package getPackage() {
jaroslav@56
   717
        return Package.getPackage(this);
jaroslav@56
   718
    }
jaroslav@56
   719
jaroslav@56
   720
jaroslav@56
   721
    /**
jaroslav@56
   722
     * Determines the interfaces implemented by the class or interface
jaroslav@56
   723
     * represented by this object.
jaroslav@56
   724
     *
jaroslav@56
   725
     * <p> If this object represents a class, the return value is an array
jaroslav@56
   726
     * containing objects representing all interfaces implemented by the
jaroslav@56
   727
     * class. The order of the interface objects in the array corresponds to
jaroslav@56
   728
     * the order of the interface names in the {@code implements} clause
jaroslav@56
   729
     * of the declaration of the class represented by this object. For
jaroslav@56
   730
     * example, given the declaration:
jaroslav@56
   731
     * <blockquote>
jaroslav@56
   732
     * {@code class Shimmer implements FloorWax, DessertTopping { ... }}
jaroslav@56
   733
     * </blockquote>
jaroslav@56
   734
     * suppose the value of {@code s} is an instance of
jaroslav@56
   735
     * {@code Shimmer}; the value of the expression:
jaroslav@56
   736
     * <blockquote>
jaroslav@56
   737
     * {@code s.getClass().getInterfaces()[0]}
jaroslav@56
   738
     * </blockquote>
jaroslav@56
   739
     * is the {@code Class} object that represents interface
jaroslav@56
   740
     * {@code FloorWax}; and the value of:
jaroslav@56
   741
     * <blockquote>
jaroslav@56
   742
     * {@code s.getClass().getInterfaces()[1]}
jaroslav@56
   743
     * </blockquote>
jaroslav@56
   744
     * is the {@code Class} object that represents interface
jaroslav@56
   745
     * {@code DessertTopping}.
jaroslav@56
   746
     *
jaroslav@56
   747
     * <p> If this object represents an interface, the array contains objects
jaroslav@56
   748
     * representing all interfaces extended by the interface. The order of the
jaroslav@56
   749
     * interface objects in the array corresponds to the order of the interface
jaroslav@56
   750
     * names in the {@code extends} clause of the declaration of the
jaroslav@56
   751
     * interface represented by this object.
jaroslav@56
   752
     *
jaroslav@56
   753
     * <p> If this object represents a class or interface that implements no
jaroslav@56
   754
     * interfaces, the method returns an array of length 0.
jaroslav@56
   755
     *
jaroslav@56
   756
     * <p> If this object represents a primitive type or void, the method
jaroslav@56
   757
     * returns an array of length 0.
jaroslav@56
   758
     *
jaroslav@56
   759
     * @return an array of interfaces implemented by this class.
jaroslav@56
   760
     */
jaroslav@56
   761
    public native Class<?>[] getInterfaces();
jaroslav@56
   762
jaroslav@56
   763
    /**
jaroslav@56
   764
     * Returns the {@code Type}s representing the interfaces
jaroslav@56
   765
     * directly implemented by the class or interface represented by
jaroslav@56
   766
     * this object.
jaroslav@56
   767
     *
jaroslav@56
   768
     * <p>If a superinterface is a parameterized type, the
jaroslav@56
   769
     * {@code Type} object returned for it must accurately reflect
jaroslav@56
   770
     * the actual type parameters used in the source code. The
jaroslav@56
   771
     * parameterized type representing each superinterface is created
jaroslav@56
   772
     * if it had not been created before. See the declaration of
jaroslav@56
   773
     * {@link java.lang.reflect.ParameterizedType ParameterizedType}
jaroslav@56
   774
     * for the semantics of the creation process for parameterized
jaroslav@56
   775
     * types.
jaroslav@56
   776
     *
jaroslav@56
   777
     * <p> If this object represents a class, the return value is an
jaroslav@56
   778
     * array containing objects representing all interfaces
jaroslav@56
   779
     * implemented by the class. The order of the interface objects in
jaroslav@56
   780
     * the array corresponds to the order of the interface names in
jaroslav@56
   781
     * the {@code implements} clause of the declaration of the class
jaroslav@56
   782
     * represented by this object.  In the case of an array class, the
jaroslav@56
   783
     * interfaces {@code Cloneable} and {@code Serializable} are
jaroslav@56
   784
     * returned in that order.
jaroslav@56
   785
     *
jaroslav@56
   786
     * <p>If this object represents an interface, the array contains
jaroslav@56
   787
     * objects representing all interfaces directly extended by the
jaroslav@56
   788
     * interface.  The order of the interface objects in the array
jaroslav@56
   789
     * corresponds to the order of the interface names in the
jaroslav@56
   790
     * {@code extends} clause of the declaration of the interface
jaroslav@56
   791
     * represented by this object.
jaroslav@56
   792
     *
jaroslav@56
   793
     * <p>If this object represents a class or interface that
jaroslav@56
   794
     * implements no interfaces, the method returns an array of length
jaroslav@56
   795
     * 0.
jaroslav@56
   796
     *
jaroslav@56
   797
     * <p>If this object represents a primitive type or void, the
jaroslav@56
   798
     * method returns an array of length 0.
jaroslav@56
   799
     *
jaroslav@56
   800
     * @throws java.lang.reflect.GenericSignatureFormatError
jaroslav@56
   801
     *     if the generic class signature does not conform to the format
jaroslav@56
   802
     *     specified in
jaroslav@56
   803
     *     <cite>The Java&trade; Virtual Machine Specification</cite>
jaroslav@56
   804
     * @throws TypeNotPresentException if any of the generic
jaroslav@56
   805
     *     superinterfaces refers to a non-existent type declaration
jaroslav@56
   806
     * @throws java.lang.reflect.MalformedParameterizedTypeException
jaroslav@56
   807
     *     if any of the generic superinterfaces refer to a parameterized
jaroslav@56
   808
     *     type that cannot be instantiated for any reason
jaroslav@56
   809
     * @return an array of interfaces implemented by this class
jaroslav@56
   810
     * @since 1.5
jaroslav@56
   811
     */
jaroslav@56
   812
    public Type[] getGenericInterfaces() {
jaroslav@56
   813
        if (getGenericSignature() != null)
jaroslav@56
   814
            return getGenericInfo().getSuperInterfaces();
jaroslav@56
   815
        else
jaroslav@56
   816
            return getInterfaces();
jaroslav@56
   817
    }
jaroslav@56
   818
jaroslav@56
   819
jaroslav@56
   820
    /**
jaroslav@56
   821
     * Returns the {@code Class} representing the component type of an
jaroslav@56
   822
     * array.  If this class does not represent an array class this method
jaroslav@56
   823
     * returns null.
jaroslav@56
   824
     *
jaroslav@56
   825
     * @return the {@code Class} representing the component type of this
jaroslav@56
   826
     * class if this class is an array
jaroslav@56
   827
     * @see     java.lang.reflect.Array
jaroslav@56
   828
     * @since JDK1.1
jaroslav@56
   829
     */
jaroslav@56
   830
    public native Class<?> getComponentType();
jaroslav@56
   831
jaroslav@56
   832
jaroslav@56
   833
    /**
jaroslav@56
   834
     * Returns the Java language modifiers for this class or interface, encoded
jaroslav@56
   835
     * in an integer. The modifiers consist of the Java Virtual Machine's
jaroslav@56
   836
     * constants for {@code public}, {@code protected},
jaroslav@56
   837
     * {@code private}, {@code final}, {@code static},
jaroslav@56
   838
     * {@code abstract} and {@code interface}; they should be decoded
jaroslav@56
   839
     * using the methods of class {@code Modifier}.
jaroslav@56
   840
     *
jaroslav@56
   841
     * <p> If the underlying class is an array class, then its
jaroslav@56
   842
     * {@code public}, {@code private} and {@code protected}
jaroslav@56
   843
     * modifiers are the same as those of its component type.  If this
jaroslav@56
   844
     * {@code Class} represents a primitive type or void, its
jaroslav@56
   845
     * {@code public} modifier is always {@code true}, and its
jaroslav@56
   846
     * {@code protected} and {@code private} modifiers are always
jaroslav@56
   847
     * {@code false}. If this object represents an array class, a
jaroslav@56
   848
     * primitive type or void, then its {@code final} modifier is always
jaroslav@56
   849
     * {@code true} and its interface modifier is always
jaroslav@56
   850
     * {@code false}. The values of its other modifiers are not determined
jaroslav@56
   851
     * by this specification.
jaroslav@56
   852
     *
jaroslav@56
   853
     * <p> The modifier encodings are defined in <em>The Java Virtual Machine
jaroslav@56
   854
     * Specification</em>, table 4.1.
jaroslav@56
   855
     *
jaroslav@56
   856
     * @return the {@code int} representing the modifiers for this class
jaroslav@56
   857
     * @see     java.lang.reflect.Modifier
jaroslav@56
   858
     * @since JDK1.1
jaroslav@56
   859
     */
jaroslav@56
   860
    public native int getModifiers();
jaroslav@56
   861
jaroslav@56
   862
jaroslav@56
   863
    /**
jaroslav@56
   864
     * Gets the signers of this class.
jaroslav@56
   865
     *
jaroslav@56
   866
     * @return  the signers of this class, or null if there are no signers.  In
jaroslav@56
   867
     *          particular, this method returns null if this object represents
jaroslav@56
   868
     *          a primitive type or void.
jaroslav@56
   869
     * @since   JDK1.1
jaroslav@56
   870
     */
jaroslav@56
   871
    public native Object[] getSigners();
jaroslav@56
   872
jaroslav@56
   873
jaroslav@56
   874
    /**
jaroslav@56
   875
     * Set the signers of this class.
jaroslav@56
   876
     */
jaroslav@56
   877
    native void setSigners(Object[] signers);
jaroslav@56
   878
jaroslav@56
   879
jaroslav@56
   880
    /**
jaroslav@56
   881
     * If this {@code Class} object represents a local or anonymous
jaroslav@56
   882
     * class within a method, returns a {@link
jaroslav@56
   883
     * java.lang.reflect.Method Method} object representing the
jaroslav@56
   884
     * immediately enclosing method of the underlying class. Returns
jaroslav@56
   885
     * {@code null} otherwise.
jaroslav@56
   886
     *
jaroslav@56
   887
     * In particular, this method returns {@code null} if the underlying
jaroslav@56
   888
     * class is a local or anonymous class immediately enclosed by a type
jaroslav@56
   889
     * declaration, instance initializer or static initializer.
jaroslav@56
   890
     *
jaroslav@56
   891
     * @return the immediately enclosing method of the underlying class, if
jaroslav@56
   892
     *     that class is a local or anonymous class; otherwise {@code null}.
jaroslav@56
   893
     * @since 1.5
jaroslav@56
   894
     */
jaroslav@56
   895
    public Method getEnclosingMethod() {
jaroslav@56
   896
        EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
jaroslav@56
   897
jaroslav@56
   898
        if (enclosingInfo == null)
jaroslav@56
   899
            return null;
jaroslav@56
   900
        else {
jaroslav@56
   901
            if (!enclosingInfo.isMethod())
jaroslav@56
   902
                return null;
jaroslav@56
   903
jaroslav@56
   904
            MethodRepository typeInfo = MethodRepository.make(enclosingInfo.getDescriptor(),
jaroslav@56
   905
                                                              getFactory());
jaroslav@56
   906
            Class<?>   returnType       = toClass(typeInfo.getReturnType());
jaroslav@56
   907
            Type []    parameterTypes   = typeInfo.getParameterTypes();
jaroslav@56
   908
            Class<?>[] parameterClasses = new Class<?>[parameterTypes.length];
jaroslav@56
   909
jaroslav@56
   910
            // Convert Types to Classes; returned types *should*
jaroslav@56
   911
            // be class objects since the methodDescriptor's used
jaroslav@56
   912
            // don't have generics information
jaroslav@56
   913
            for(int i = 0; i < parameterClasses.length; i++)
jaroslav@56
   914
                parameterClasses[i] = toClass(parameterTypes[i]);
jaroslav@56
   915
jaroslav@56
   916
            /*
jaroslav@56
   917
             * Loop over all declared methods; match method name,
jaroslav@56
   918
             * number of and type of parameters, *and* return
jaroslav@56
   919
             * type.  Matching return type is also necessary
jaroslav@56
   920
             * because of covariant returns, etc.
jaroslav@56
   921
             */
jaroslav@56
   922
            for(Method m: enclosingInfo.getEnclosingClass().getDeclaredMethods()) {
jaroslav@56
   923
                if (m.getName().equals(enclosingInfo.getName()) ) {
jaroslav@56
   924
                    Class<?>[] candidateParamClasses = m.getParameterTypes();
jaroslav@56
   925
                    if (candidateParamClasses.length == parameterClasses.length) {
jaroslav@56
   926
                        boolean matches = true;
jaroslav@56
   927
                        for(int i = 0; i < candidateParamClasses.length; i++) {
jaroslav@56
   928
                            if (!candidateParamClasses[i].equals(parameterClasses[i])) {
jaroslav@56
   929
                                matches = false;
jaroslav@56
   930
                                break;
jaroslav@56
   931
                            }
jaroslav@56
   932
                        }
jaroslav@56
   933
jaroslav@56
   934
                        if (matches) { // finally, check return type
jaroslav@56
   935
                            if (m.getReturnType().equals(returnType) )
jaroslav@56
   936
                                return m;
jaroslav@56
   937
                        }
jaroslav@56
   938
                    }
jaroslav@56
   939
                }
jaroslav@56
   940
            }
jaroslav@56
   941
jaroslav@56
   942
            throw new InternalError("Enclosing method not found");
jaroslav@56
   943
        }
jaroslav@56
   944
    }
jaroslav@56
   945
jaroslav@56
   946
    private native Object[] getEnclosingMethod0();
jaroslav@56
   947
jaroslav@56
   948
    private EnclosingMethodInfo getEnclosingMethodInfo() {
jaroslav@56
   949
        Object[] enclosingInfo = getEnclosingMethod0();
jaroslav@56
   950
        if (enclosingInfo == null)
jaroslav@56
   951
            return null;
jaroslav@56
   952
        else {
jaroslav@56
   953
            return new EnclosingMethodInfo(enclosingInfo);
jaroslav@56
   954
        }
jaroslav@56
   955
    }
jaroslav@56
   956
jaroslav@56
   957
    private final static class EnclosingMethodInfo {
jaroslav@56
   958
        private Class<?> enclosingClass;
jaroslav@56
   959
        private String name;
jaroslav@56
   960
        private String descriptor;
jaroslav@56
   961
jaroslav@56
   962
        private EnclosingMethodInfo(Object[] enclosingInfo) {
jaroslav@56
   963
            if (enclosingInfo.length != 3)
jaroslav@56
   964
                throw new InternalError("Malformed enclosing method information");
jaroslav@56
   965
            try {
jaroslav@56
   966
                // The array is expected to have three elements:
jaroslav@56
   967
jaroslav@56
   968
                // the immediately enclosing class
jaroslav@56
   969
                enclosingClass = (Class<?>) enclosingInfo[0];
jaroslav@56
   970
                assert(enclosingClass != null);
jaroslav@56
   971
jaroslav@56
   972
                // the immediately enclosing method or constructor's
jaroslav@56
   973
                // name (can be null).
jaroslav@56
   974
                name            = (String)   enclosingInfo[1];
jaroslav@56
   975
jaroslav@56
   976
                // the immediately enclosing method or constructor's
jaroslav@56
   977
                // descriptor (null iff name is).
jaroslav@56
   978
                descriptor      = (String)   enclosingInfo[2];
jaroslav@56
   979
                assert((name != null && descriptor != null) || name == descriptor);
jaroslav@56
   980
            } catch (ClassCastException cce) {
jaroslav@56
   981
                throw new InternalError("Invalid type in enclosing method information");
jaroslav@56
   982
            }
jaroslav@56
   983
        }
jaroslav@56
   984
jaroslav@56
   985
        boolean isPartial() {
jaroslav@56
   986
            return enclosingClass == null || name == null || descriptor == null;
jaroslav@56
   987
        }
jaroslav@56
   988
jaroslav@56
   989
        boolean isConstructor() { return !isPartial() && "<init>".equals(name); }
jaroslav@56
   990
jaroslav@56
   991
        boolean isMethod() { return !isPartial() && !isConstructor() && !"<clinit>".equals(name); }
jaroslav@56
   992
jaroslav@56
   993
        Class<?> getEnclosingClass() { return enclosingClass; }
jaroslav@56
   994
jaroslav@56
   995
        String getName() { return name; }
jaroslav@56
   996
jaroslav@56
   997
        String getDescriptor() { return descriptor; }
jaroslav@56
   998
jaroslav@56
   999
    }
jaroslav@56
  1000
jaroslav@56
  1001
    private static Class<?> toClass(Type o) {
jaroslav@56
  1002
        if (o instanceof GenericArrayType)
jaroslav@56
  1003
            return Array.newInstance(toClass(((GenericArrayType)o).getGenericComponentType()),
jaroslav@56
  1004
                                     0)
jaroslav@56
  1005
                .getClass();
jaroslav@56
  1006
        return (Class<?>)o;
jaroslav@56
  1007
     }
jaroslav@56
  1008
jaroslav@56
  1009
    /**
jaroslav@56
  1010
     * If this {@code Class} object represents a local or anonymous
jaroslav@56
  1011
     * class within a constructor, returns a {@link
jaroslav@56
  1012
     * java.lang.reflect.Constructor Constructor} object representing
jaroslav@56
  1013
     * the immediately enclosing constructor of the underlying
jaroslav@56
  1014
     * class. Returns {@code null} otherwise.  In particular, this
jaroslav@56
  1015
     * method returns {@code null} if the underlying class is a local
jaroslav@56
  1016
     * or anonymous class immediately enclosed by a type declaration,
jaroslav@56
  1017
     * instance initializer or static initializer.
jaroslav@56
  1018
     *
jaroslav@56
  1019
     * @return the immediately enclosing constructor of the underlying class, if
jaroslav@56
  1020
     *     that class is a local or anonymous class; otherwise {@code null}.
jaroslav@56
  1021
     * @since 1.5
jaroslav@56
  1022
     */
jaroslav@56
  1023
    public Constructor<?> getEnclosingConstructor() {
jaroslav@56
  1024
        EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
jaroslav@56
  1025
jaroslav@56
  1026
        if (enclosingInfo == null)
jaroslav@56
  1027
            return null;
jaroslav@56
  1028
        else {
jaroslav@56
  1029
            if (!enclosingInfo.isConstructor())
jaroslav@56
  1030
                return null;
jaroslav@56
  1031
jaroslav@56
  1032
            ConstructorRepository typeInfo = ConstructorRepository.make(enclosingInfo.getDescriptor(),
jaroslav@56
  1033
                                                                        getFactory());
jaroslav@56
  1034
            Type []    parameterTypes   = typeInfo.getParameterTypes();
jaroslav@56
  1035
            Class<?>[] parameterClasses = new Class<?>[parameterTypes.length];
jaroslav@56
  1036
jaroslav@56
  1037
            // Convert Types to Classes; returned types *should*
jaroslav@56
  1038
            // be class objects since the methodDescriptor's used
jaroslav@56
  1039
            // don't have generics information
jaroslav@56
  1040
            for(int i = 0; i < parameterClasses.length; i++)
jaroslav@56
  1041
                parameterClasses[i] = toClass(parameterTypes[i]);
jaroslav@56
  1042
jaroslav@56
  1043
            /*
jaroslav@56
  1044
             * Loop over all declared constructors; match number
jaroslav@56
  1045
             * of and type of parameters.
jaroslav@56
  1046
             */
jaroslav@56
  1047
            for(Constructor<?> c: enclosingInfo.getEnclosingClass().getDeclaredConstructors()) {
jaroslav@56
  1048
                Class<?>[] candidateParamClasses = c.getParameterTypes();
jaroslav@56
  1049
                if (candidateParamClasses.length == parameterClasses.length) {
jaroslav@56
  1050
                    boolean matches = true;
jaroslav@56
  1051
                    for(int i = 0; i < candidateParamClasses.length; i++) {
jaroslav@56
  1052
                        if (!candidateParamClasses[i].equals(parameterClasses[i])) {
jaroslav@56
  1053
                            matches = false;
jaroslav@56
  1054
                            break;
jaroslav@56
  1055
                        }
jaroslav@56
  1056
                    }
jaroslav@56
  1057
jaroslav@56
  1058
                    if (matches)
jaroslav@56
  1059
                        return c;
jaroslav@56
  1060
                }
jaroslav@56
  1061
            }
jaroslav@56
  1062
jaroslav@56
  1063
            throw new InternalError("Enclosing constructor not found");
jaroslav@56
  1064
        }
jaroslav@56
  1065
    }
jaroslav@56
  1066
jaroslav@56
  1067
jaroslav@56
  1068
    /**
jaroslav@56
  1069
     * If the class or interface represented by this {@code Class} object
jaroslav@56
  1070
     * is a member of another class, returns the {@code Class} object
jaroslav@56
  1071
     * representing the class in which it was declared.  This method returns
jaroslav@56
  1072
     * null if this class or interface is not a member of any other class.  If
jaroslav@56
  1073
     * this {@code Class} object represents an array class, a primitive
jaroslav@56
  1074
     * type, or void,then this method returns null.
jaroslav@56
  1075
     *
jaroslav@56
  1076
     * @return the declaring class for this class
jaroslav@56
  1077
     * @since JDK1.1
jaroslav@56
  1078
     */
jaroslav@56
  1079
    public native Class<?> getDeclaringClass();
jaroslav@56
  1080
jaroslav@56
  1081
jaroslav@56
  1082
    /**
jaroslav@56
  1083
     * Returns the immediately enclosing class of the underlying
jaroslav@56
  1084
     * class.  If the underlying class is a top level class this
jaroslav@56
  1085
     * method returns {@code null}.
jaroslav@56
  1086
     * @return the immediately enclosing class of the underlying class
jaroslav@56
  1087
     * @since 1.5
jaroslav@56
  1088
     */
jaroslav@56
  1089
    public Class<?> getEnclosingClass() {
jaroslav@56
  1090
        // There are five kinds of classes (or interfaces):
jaroslav@56
  1091
        // a) Top level classes
jaroslav@56
  1092
        // b) Nested classes (static member classes)
jaroslav@56
  1093
        // c) Inner classes (non-static member classes)
jaroslav@56
  1094
        // d) Local classes (named classes declared within a method)
jaroslav@56
  1095
        // e) Anonymous classes
jaroslav@56
  1096
jaroslav@56
  1097
jaroslav@56
  1098
        // JVM Spec 4.8.6: A class must have an EnclosingMethod
jaroslav@56
  1099
        // attribute if and only if it is a local class or an
jaroslav@56
  1100
        // anonymous class.
jaroslav@56
  1101
        EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
jaroslav@56
  1102
jaroslav@56
  1103
        if (enclosingInfo == null) {
jaroslav@56
  1104
            // This is a top level or a nested class or an inner class (a, b, or c)
jaroslav@56
  1105
            return getDeclaringClass();
jaroslav@56
  1106
        } else {
jaroslav@56
  1107
            Class<?> enclosingClass = enclosingInfo.getEnclosingClass();
jaroslav@56
  1108
            // This is a local class or an anonymous class (d or e)
jaroslav@56
  1109
            if (enclosingClass == this || enclosingClass == null)
jaroslav@56
  1110
                throw new InternalError("Malformed enclosing method information");
jaroslav@56
  1111
            else
jaroslav@56
  1112
                return enclosingClass;
jaroslav@56
  1113
        }
jaroslav@56
  1114
    }
jaroslav@56
  1115
jaroslav@56
  1116
    /**
jaroslav@56
  1117
     * Returns the simple name of the underlying class as given in the
jaroslav@56
  1118
     * source code. Returns an empty string if the underlying class is
jaroslav@56
  1119
     * anonymous.
jaroslav@56
  1120
     *
jaroslav@56
  1121
     * <p>The simple name of an array is the simple name of the
jaroslav@56
  1122
     * component type with "[]" appended.  In particular the simple
jaroslav@56
  1123
     * name of an array whose component type is anonymous is "[]".
jaroslav@56
  1124
     *
jaroslav@56
  1125
     * @return the simple name of the underlying class
jaroslav@56
  1126
     * @since 1.5
jaroslav@56
  1127
     */
jaroslav@56
  1128
    public String getSimpleName() {
jaroslav@56
  1129
        if (isArray())
jaroslav@56
  1130
            return getComponentType().getSimpleName()+"[]";
jaroslav@56
  1131
jaroslav@56
  1132
        String simpleName = getSimpleBinaryName();
jaroslav@56
  1133
        if (simpleName == null) { // top level class
jaroslav@56
  1134
            simpleName = getName();
jaroslav@56
  1135
            return simpleName.substring(simpleName.lastIndexOf(".")+1); // strip the package name
jaroslav@56
  1136
        }
jaroslav@56
  1137
        // According to JLS3 "Binary Compatibility" (13.1) the binary
jaroslav@56
  1138
        // name of non-package classes (not top level) is the binary
jaroslav@56
  1139
        // name of the immediately enclosing class followed by a '$' followed by:
jaroslav@56
  1140
        // (for nested and inner classes): the simple name.
jaroslav@56
  1141
        // (for local classes): 1 or more digits followed by the simple name.
jaroslav@56
  1142
        // (for anonymous classes): 1 or more digits.
jaroslav@56
  1143
jaroslav@56
  1144
        // Since getSimpleBinaryName() will strip the binary name of
jaroslav@56
  1145
        // the immediatly enclosing class, we are now looking at a
jaroslav@56
  1146
        // string that matches the regular expression "\$[0-9]*"
jaroslav@56
  1147
        // followed by a simple name (considering the simple of an
jaroslav@56
  1148
        // anonymous class to be the empty string).
jaroslav@56
  1149
jaroslav@56
  1150
        // Remove leading "\$[0-9]*" from the name
jaroslav@56
  1151
        int length = simpleName.length();
jaroslav@56
  1152
        if (length < 1 || simpleName.charAt(0) != '$')
jaroslav@56
  1153
            throw new InternalError("Malformed class name");
jaroslav@56
  1154
        int index = 1;
jaroslav@56
  1155
        while (index < length && isAsciiDigit(simpleName.charAt(index)))
jaroslav@56
  1156
            index++;
jaroslav@56
  1157
        // Eventually, this is the empty string iff this is an anonymous class
jaroslav@56
  1158
        return simpleName.substring(index);
jaroslav@56
  1159
    }
jaroslav@56
  1160
jaroslav@56
  1161
    /**
jaroslav@56
  1162
     * Character.isDigit answers {@code true} to some non-ascii
jaroslav@56
  1163
     * digits.  This one does not.
jaroslav@56
  1164
     */
jaroslav@56
  1165
    private static boolean isAsciiDigit(char c) {
jaroslav@56
  1166
        return '0' <= c && c <= '9';
jaroslav@56
  1167
    }
jaroslav@56
  1168
jaroslav@56
  1169
    /**
jaroslav@56
  1170
     * Returns the canonical name of the underlying class as
jaroslav@56
  1171
     * defined by the Java Language Specification.  Returns null if
jaroslav@56
  1172
     * the underlying class does not have a canonical name (i.e., if
jaroslav@56
  1173
     * it is a local or anonymous class or an array whose component
jaroslav@56
  1174
     * type does not have a canonical name).
jaroslav@56
  1175
     * @return the canonical name of the underlying class if it exists, and
jaroslav@56
  1176
     * {@code null} otherwise.
jaroslav@56
  1177
     * @since 1.5
jaroslav@56
  1178
     */
jaroslav@56
  1179
    public String getCanonicalName() {
jaroslav@56
  1180
        if (isArray()) {
jaroslav@56
  1181
            String canonicalName = getComponentType().getCanonicalName();
jaroslav@56
  1182
            if (canonicalName != null)
jaroslav@56
  1183
                return canonicalName + "[]";
jaroslav@56
  1184
            else
jaroslav@56
  1185
                return null;
jaroslav@56
  1186
        }
jaroslav@56
  1187
        if (isLocalOrAnonymousClass())
jaroslav@56
  1188
            return null;
jaroslav@56
  1189
        Class<?> enclosingClass = getEnclosingClass();
jaroslav@56
  1190
        if (enclosingClass == null) { // top level class
jaroslav@56
  1191
            return getName();
jaroslav@56
  1192
        } else {
jaroslav@56
  1193
            String enclosingName = enclosingClass.getCanonicalName();
jaroslav@56
  1194
            if (enclosingName == null)
jaroslav@56
  1195
                return null;
jaroslav@56
  1196
            return enclosingName + "." + getSimpleName();
jaroslav@56
  1197
        }
jaroslav@56
  1198
    }
jaroslav@56
  1199
jaroslav@56
  1200
    /**
jaroslav@56
  1201
     * Returns {@code true} if and only if the underlying class
jaroslav@56
  1202
     * is an anonymous class.
jaroslav@56
  1203
     *
jaroslav@56
  1204
     * @return {@code true} if and only if this class is an anonymous class.
jaroslav@56
  1205
     * @since 1.5
jaroslav@56
  1206
     */
jaroslav@56
  1207
    public boolean isAnonymousClass() {
jaroslav@56
  1208
        return "".equals(getSimpleName());
jaroslav@56
  1209
    }
jaroslav@56
  1210
jaroslav@56
  1211
    /**
jaroslav@56
  1212
     * Returns {@code true} if and only if the underlying class
jaroslav@56
  1213
     * is a local class.
jaroslav@56
  1214
     *
jaroslav@56
  1215
     * @return {@code true} if and only if this class is a local class.
jaroslav@56
  1216
     * @since 1.5
jaroslav@56
  1217
     */
jaroslav@56
  1218
    public boolean isLocalClass() {
jaroslav@56
  1219
        return isLocalOrAnonymousClass() && !isAnonymousClass();
jaroslav@56
  1220
    }
jaroslav@56
  1221
jaroslav@56
  1222
    /**
jaroslav@56
  1223
     * Returns {@code true} if and only if the underlying class
jaroslav@56
  1224
     * is a member class.
jaroslav@56
  1225
     *
jaroslav@56
  1226
     * @return {@code true} if and only if this class is a member class.
jaroslav@56
  1227
     * @since 1.5
jaroslav@56
  1228
     */
jaroslav@56
  1229
    public boolean isMemberClass() {
jaroslav@56
  1230
        return getSimpleBinaryName() != null && !isLocalOrAnonymousClass();
jaroslav@56
  1231
    }
jaroslav@56
  1232
jaroslav@56
  1233
    /**
jaroslav@56
  1234
     * Returns the "simple binary name" of the underlying class, i.e.,
jaroslav@56
  1235
     * the binary name without the leading enclosing class name.
jaroslav@56
  1236
     * Returns {@code null} if the underlying class is a top level
jaroslav@56
  1237
     * class.
jaroslav@56
  1238
     */
jaroslav@56
  1239
    private String getSimpleBinaryName() {
jaroslav@56
  1240
        Class<?> enclosingClass = getEnclosingClass();
jaroslav@56
  1241
        if (enclosingClass == null) // top level class
jaroslav@56
  1242
            return null;
jaroslav@56
  1243
        // Otherwise, strip the enclosing class' name
jaroslav@56
  1244
        try {
jaroslav@56
  1245
            return getName().substring(enclosingClass.getName().length());
jaroslav@56
  1246
        } catch (IndexOutOfBoundsException ex) {
jaroslav@56
  1247
            throw new InternalError("Malformed class name");
jaroslav@56
  1248
        }
jaroslav@56
  1249
    }
jaroslav@56
  1250
jaroslav@56
  1251
    /**
jaroslav@56
  1252
     * Returns {@code true} if this is a local class or an anonymous
jaroslav@56
  1253
     * class.  Returns {@code false} otherwise.
jaroslav@56
  1254
     */
jaroslav@56
  1255
    private boolean isLocalOrAnonymousClass() {
jaroslav@56
  1256
        // JVM Spec 4.8.6: A class must have an EnclosingMethod
jaroslav@56
  1257
        // attribute if and only if it is a local class or an
jaroslav@56
  1258
        // anonymous class.
jaroslav@56
  1259
        return getEnclosingMethodInfo() != null;
jaroslav@56
  1260
    }
jaroslav@56
  1261
jaroslav@56
  1262
    /**
jaroslav@56
  1263
     * Returns an array containing {@code Class} objects representing all
jaroslav@56
  1264
     * the public classes and interfaces that are members of the class
jaroslav@56
  1265
     * represented by this {@code Class} object.  This includes public
jaroslav@56
  1266
     * class and interface members inherited from superclasses and public class
jaroslav@56
  1267
     * and interface members declared by the class.  This method returns an
jaroslav@56
  1268
     * array of length 0 if this {@code Class} object has no public member
jaroslav@56
  1269
     * classes or interfaces.  This method also returns an array of length 0 if
jaroslav@56
  1270
     * this {@code Class} object represents a primitive type, an array
jaroslav@56
  1271
     * class, or void.
jaroslav@56
  1272
     *
jaroslav@56
  1273
     * @return the array of {@code Class} objects representing the public
jaroslav@56
  1274
     * members of this class
jaroslav@56
  1275
     * @exception  SecurityException
jaroslav@56
  1276
     *             If a security manager, <i>s</i>, is present and any of the
jaroslav@56
  1277
     *             following conditions is met:
jaroslav@56
  1278
     *
jaroslav@56
  1279
     *             <ul>
jaroslav@56
  1280
     *
jaroslav@56
  1281
     *             <li> invocation of
jaroslav@56
  1282
     *             {@link SecurityManager#checkMemberAccess
jaroslav@56
  1283
     *             s.checkMemberAccess(this, Member.PUBLIC)} method
jaroslav@56
  1284
     *             denies access to the classes within this class
jaroslav@56
  1285
     *
jaroslav@56
  1286
     *             <li> the caller's class loader is not the same as or an
jaroslav@56
  1287
     *             ancestor of the class loader for the current class and
jaroslav@56
  1288
     *             invocation of {@link SecurityManager#checkPackageAccess
jaroslav@56
  1289
     *             s.checkPackageAccess()} denies access to the package
jaroslav@56
  1290
     *             of this class
jaroslav@56
  1291
     *
jaroslav@56
  1292
     *             </ul>
jaroslav@56
  1293
     *
jaroslav@56
  1294
     * @since JDK1.1
jaroslav@56
  1295
     */
jaroslav@56
  1296
    public Class<?>[] getClasses() {
jaroslav@56
  1297
        // be very careful not to change the stack depth of this
jaroslav@56
  1298
        // checkMemberAccess call for security reasons
jaroslav@56
  1299
        // see java.lang.SecurityManager.checkMemberAccess
jaroslav@56
  1300
        checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
jaroslav@56
  1301
jaroslav@56
  1302
        // Privileged so this implementation can look at DECLARED classes,
jaroslav@56
  1303
        // something the caller might not have privilege to do.  The code here
jaroslav@56
  1304
        // is allowed to look at DECLARED classes because (1) it does not hand
jaroslav@56
  1305
        // out anything other than public members and (2) public member access
jaroslav@56
  1306
        // has already been ok'd by the SecurityManager.
jaroslav@56
  1307
jaroslav@56
  1308
        return java.security.AccessController.doPrivileged(
jaroslav@56
  1309
            new java.security.PrivilegedAction<Class<?>[]>() {
jaroslav@56
  1310
                public Class[] run() {
jaroslav@56
  1311
                    List<Class<?>> list = new ArrayList<>();
jaroslav@56
  1312
                    Class<?> currentClass = Class.this;
jaroslav@56
  1313
                    while (currentClass != null) {
jaroslav@56
  1314
                        Class<?>[] members = currentClass.getDeclaredClasses();
jaroslav@56
  1315
                        for (int i = 0; i < members.length; i++) {
jaroslav@56
  1316
                            if (Modifier.isPublic(members[i].getModifiers())) {
jaroslav@56
  1317
                                list.add(members[i]);
jaroslav@56
  1318
                            }
jaroslav@56
  1319
                        }
jaroslav@56
  1320
                        currentClass = currentClass.getSuperclass();
jaroslav@56
  1321
                    }
jaroslav@56
  1322
                    return list.toArray(new Class[0]);
jaroslav@56
  1323
                }
jaroslav@56
  1324
            });
jaroslav@56
  1325
    }
jaroslav@56
  1326
jaroslav@56
  1327
jaroslav@56
  1328
    /**
jaroslav@56
  1329
     * Returns an array containing {@code Field} objects reflecting all
jaroslav@56
  1330
     * the accessible public fields of the class or interface represented by
jaroslav@56
  1331
     * this {@code Class} object.  The elements in the array returned are
jaroslav@56
  1332
     * not sorted and are not in any particular order.  This method returns an
jaroslav@56
  1333
     * array of length 0 if the class or interface has no accessible public
jaroslav@56
  1334
     * fields, or if it represents an array class, a primitive type, or void.
jaroslav@56
  1335
     *
jaroslav@56
  1336
     * <p> Specifically, if this {@code Class} object represents a class,
jaroslav@56
  1337
     * this method returns the public fields of this class and of all its
jaroslav@56
  1338
     * superclasses.  If this {@code Class} object represents an
jaroslav@56
  1339
     * interface, this method returns the fields of this interface and of all
jaroslav@56
  1340
     * its superinterfaces.
jaroslav@56
  1341
     *
jaroslav@56
  1342
     * <p> The implicit length field for array class is not reflected by this
jaroslav@56
  1343
     * method. User code should use the methods of class {@code Array} to
jaroslav@56
  1344
     * manipulate arrays.
jaroslav@56
  1345
     *
jaroslav@56
  1346
     * <p> See <em>The Java Language Specification</em>, sections 8.2 and 8.3.
jaroslav@56
  1347
     *
jaroslav@56
  1348
     * @return the array of {@code Field} objects representing the
jaroslav@56
  1349
     * public fields
jaroslav@56
  1350
     * @exception  SecurityException
jaroslav@56
  1351
     *             If a security manager, <i>s</i>, is present and any of the
jaroslav@56
  1352
     *             following conditions is met:
jaroslav@56
  1353
     *
jaroslav@56
  1354
     *             <ul>
jaroslav@56
  1355
     *
jaroslav@56
  1356
     *             <li> invocation of
jaroslav@56
  1357
     *             {@link SecurityManager#checkMemberAccess
jaroslav@56
  1358
     *             s.checkMemberAccess(this, Member.PUBLIC)} denies
jaroslav@56
  1359
     *             access to the fields within this class
jaroslav@56
  1360
     *
jaroslav@56
  1361
     *             <li> the caller's class loader is not the same as or an
jaroslav@56
  1362
     *             ancestor of the class loader for the current class and
jaroslav@56
  1363
     *             invocation of {@link SecurityManager#checkPackageAccess
jaroslav@56
  1364
     *             s.checkPackageAccess()} denies access to the package
jaroslav@56
  1365
     *             of this class
jaroslav@56
  1366
     *
jaroslav@56
  1367
     *             </ul>
jaroslav@56
  1368
     *
jaroslav@56
  1369
     * @since JDK1.1
jaroslav@56
  1370
     */
jaroslav@56
  1371
    public Field[] getFields() throws SecurityException {
jaroslav@56
  1372
        // be very careful not to change the stack depth of this
jaroslav@56
  1373
        // checkMemberAccess call for security reasons
jaroslav@56
  1374
        // see java.lang.SecurityManager.checkMemberAccess
jaroslav@56
  1375
        checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
jaroslav@56
  1376
        return copyFields(privateGetPublicFields(null));
jaroslav@56
  1377
    }
jaroslav@56
  1378
jaroslav@56
  1379
jaroslav@56
  1380
    /**
jaroslav@56
  1381
     * Returns an array containing {@code Method} objects reflecting all
jaroslav@56
  1382
     * the public <em>member</em> methods of the class or interface represented
jaroslav@56
  1383
     * by this {@code Class} object, including those declared by the class
jaroslav@56
  1384
     * or interface and those inherited from superclasses and
jaroslav@56
  1385
     * superinterfaces.  Array classes return all the (public) member methods
jaroslav@56
  1386
     * inherited from the {@code Object} class.  The elements in the array
jaroslav@56
  1387
     * returned are not sorted and are not in any particular order.  This
jaroslav@56
  1388
     * method returns an array of length 0 if this {@code Class} object
jaroslav@56
  1389
     * represents a class or interface that has no public member methods, or if
jaroslav@56
  1390
     * this {@code Class} object represents a primitive type or void.
jaroslav@56
  1391
     *
jaroslav@56
  1392
     * <p> The class initialization method {@code <clinit>} is not
jaroslav@56
  1393
     * included in the returned array. If the class declares multiple public
jaroslav@56
  1394
     * member methods with the same parameter types, they are all included in
jaroslav@56
  1395
     * the returned array.
jaroslav@56
  1396
     *
jaroslav@56
  1397
     * <p> See <em>The Java Language Specification</em>, sections 8.2 and 8.4.
jaroslav@56
  1398
     *
jaroslav@56
  1399
     * @return the array of {@code Method} objects representing the
jaroslav@56
  1400
     * public methods of this class
jaroslav@56
  1401
     * @exception  SecurityException
jaroslav@56
  1402
     *             If a security manager, <i>s</i>, is present and any of the
jaroslav@56
  1403
     *             following conditions is met:
jaroslav@56
  1404
     *
jaroslav@56
  1405
     *             <ul>
jaroslav@56
  1406
     *
jaroslav@56
  1407
     *             <li> invocation of
jaroslav@56
  1408
     *             {@link SecurityManager#checkMemberAccess
jaroslav@56
  1409
     *             s.checkMemberAccess(this, Member.PUBLIC)} denies
jaroslav@56
  1410
     *             access to the methods within this class
jaroslav@56
  1411
     *
jaroslav@56
  1412
     *             <li> the caller's class loader is not the same as or an
jaroslav@56
  1413
     *             ancestor of the class loader for the current class and
jaroslav@56
  1414
     *             invocation of {@link SecurityManager#checkPackageAccess
jaroslav@56
  1415
     *             s.checkPackageAccess()} denies access to the package
jaroslav@56
  1416
     *             of this class
jaroslav@56
  1417
     *
jaroslav@56
  1418
     *             </ul>
jaroslav@56
  1419
     *
jaroslav@56
  1420
     * @since JDK1.1
jaroslav@56
  1421
     */
jaroslav@56
  1422
    public Method[] getMethods() throws SecurityException {
jaroslav@56
  1423
        // be very careful not to change the stack depth of this
jaroslav@56
  1424
        // checkMemberAccess call for security reasons
jaroslav@56
  1425
        // see java.lang.SecurityManager.checkMemberAccess
jaroslav@56
  1426
        checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
jaroslav@56
  1427
        return copyMethods(privateGetPublicMethods());
jaroslav@56
  1428
    }
jaroslav@56
  1429
jaroslav@56
  1430
jaroslav@56
  1431
    /**
jaroslav@56
  1432
     * Returns an array containing {@code Constructor} objects reflecting
jaroslav@56
  1433
     * all the public constructors of the class represented by this
jaroslav@56
  1434
     * {@code Class} object.  An array of length 0 is returned if the
jaroslav@56
  1435
     * class has no public constructors, or if the class is an array class, or
jaroslav@56
  1436
     * if the class reflects a primitive type or void.
jaroslav@56
  1437
     *
jaroslav@56
  1438
     * Note that while this method returns an array of {@code
jaroslav@56
  1439
     * Constructor<T>} objects (that is an array of constructors from
jaroslav@56
  1440
     * this class), the return type of this method is {@code
jaroslav@56
  1441
     * Constructor<?>[]} and <em>not</em> {@code Constructor<T>[]} as
jaroslav@56
  1442
     * might be expected.  This less informative return type is
jaroslav@56
  1443
     * necessary since after being returned from this method, the
jaroslav@56
  1444
     * array could be modified to hold {@code Constructor} objects for
jaroslav@56
  1445
     * different classes, which would violate the type guarantees of
jaroslav@56
  1446
     * {@code Constructor<T>[]}.
jaroslav@56
  1447
     *
jaroslav@56
  1448
     * @return the array of {@code Constructor} objects representing the
jaroslav@56
  1449
     *  public constructors of this class
jaroslav@56
  1450
     * @exception  SecurityException
jaroslav@56
  1451
     *             If a security manager, <i>s</i>, is present and any of the
jaroslav@56
  1452
     *             following conditions is met:
jaroslav@56
  1453
     *
jaroslav@56
  1454
     *             <ul>
jaroslav@56
  1455
     *
jaroslav@56
  1456
     *             <li> invocation of
jaroslav@56
  1457
     *             {@link SecurityManager#checkMemberAccess
jaroslav@56
  1458
     *             s.checkMemberAccess(this, Member.PUBLIC)} denies
jaroslav@56
  1459
     *             access to the constructors within this class
jaroslav@56
  1460
     *
jaroslav@56
  1461
     *             <li> the caller's class loader is not the same as or an
jaroslav@56
  1462
     *             ancestor of the class loader for the current class and
jaroslav@56
  1463
     *             invocation of {@link SecurityManager#checkPackageAccess
jaroslav@56
  1464
     *             s.checkPackageAccess()} denies access to the package
jaroslav@56
  1465
     *             of this class
jaroslav@56
  1466
     *
jaroslav@56
  1467
     *             </ul>
jaroslav@56
  1468
     *
jaroslav@56
  1469
     * @since JDK1.1
jaroslav@56
  1470
     */
jaroslav@56
  1471
    public Constructor<?>[] getConstructors() throws SecurityException {
jaroslav@56
  1472
        // be very careful not to change the stack depth of this
jaroslav@56
  1473
        // checkMemberAccess call for security reasons
jaroslav@56
  1474
        // see java.lang.SecurityManager.checkMemberAccess
jaroslav@56
  1475
        checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
jaroslav@56
  1476
        return copyConstructors(privateGetDeclaredConstructors(true));
jaroslav@56
  1477
    }
jaroslav@56
  1478
jaroslav@56
  1479
jaroslav@56
  1480
    /**
jaroslav@56
  1481
     * Returns a {@code Field} object that reflects the specified public
jaroslav@56
  1482
     * member field of the class or interface represented by this
jaroslav@56
  1483
     * {@code Class} object. The {@code name} parameter is a
jaroslav@56
  1484
     * {@code String} specifying the simple name of the desired field.
jaroslav@56
  1485
     *
jaroslav@56
  1486
     * <p> The field to be reflected is determined by the algorithm that
jaroslav@56
  1487
     * follows.  Let C be the class represented by this object:
jaroslav@56
  1488
     * <OL>
jaroslav@56
  1489
     * <LI> If C declares a public field with the name specified, that is the
jaroslav@56
  1490
     *      field to be reflected.</LI>
jaroslav@56
  1491
     * <LI> If no field was found in step 1 above, this algorithm is applied
jaroslav@56
  1492
     *      recursively to each direct superinterface of C. The direct
jaroslav@56
  1493
     *      superinterfaces are searched in the order they were declared.</LI>
jaroslav@56
  1494
     * <LI> If no field was found in steps 1 and 2 above, and C has a
jaroslav@56
  1495
     *      superclass S, then this algorithm is invoked recursively upon S.
jaroslav@56
  1496
     *      If C has no superclass, then a {@code NoSuchFieldException}
jaroslav@56
  1497
     *      is thrown.</LI>
jaroslav@56
  1498
     * </OL>
jaroslav@56
  1499
     *
jaroslav@56
  1500
     * <p> See <em>The Java Language Specification</em>, sections 8.2 and 8.3.
jaroslav@56
  1501
     *
jaroslav@56
  1502
     * @param name the field name
jaroslav@56
  1503
     * @return  the {@code Field} object of this class specified by
jaroslav@56
  1504
     * {@code name}
jaroslav@56
  1505
     * @exception NoSuchFieldException if a field with the specified name is
jaroslav@56
  1506
     *              not found.
jaroslav@56
  1507
     * @exception NullPointerException if {@code name} is {@code null}
jaroslav@56
  1508
     * @exception  SecurityException
jaroslav@56
  1509
     *             If a security manager, <i>s</i>, is present and any of the
jaroslav@56
  1510
     *             following conditions is met:
jaroslav@56
  1511
     *
jaroslav@56
  1512
     *             <ul>
jaroslav@56
  1513
     *
jaroslav@56
  1514
     *             <li> invocation of
jaroslav@56
  1515
     *             {@link SecurityManager#checkMemberAccess
jaroslav@56
  1516
     *             s.checkMemberAccess(this, Member.PUBLIC)} denies
jaroslav@56
  1517
     *             access to the field
jaroslav@56
  1518
     *
jaroslav@56
  1519
     *             <li> the caller's class loader is not the same as or an
jaroslav@56
  1520
     *             ancestor of the class loader for the current class and
jaroslav@56
  1521
     *             invocation of {@link SecurityManager#checkPackageAccess
jaroslav@56
  1522
     *             s.checkPackageAccess()} denies access to the package
jaroslav@56
  1523
     *             of this class
jaroslav@56
  1524
     *
jaroslav@56
  1525
     *             </ul>
jaroslav@56
  1526
     *
jaroslav@56
  1527
     * @since JDK1.1
jaroslav@56
  1528
     */
jaroslav@56
  1529
    public Field getField(String name)
jaroslav@56
  1530
        throws NoSuchFieldException, SecurityException {
jaroslav@56
  1531
        // be very careful not to change the stack depth of this
jaroslav@56
  1532
        // checkMemberAccess call for security reasons
jaroslav@56
  1533
        // see java.lang.SecurityManager.checkMemberAccess
jaroslav@56
  1534
        checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
jaroslav@56
  1535
        Field field = getField0(name);
jaroslav@56
  1536
        if (field == null) {
jaroslav@56
  1537
            throw new NoSuchFieldException(name);
jaroslav@56
  1538
        }
jaroslav@56
  1539
        return field;
jaroslav@56
  1540
    }
jaroslav@56
  1541
jaroslav@56
  1542
jaroslav@56
  1543
    /**
jaroslav@56
  1544
     * Returns a {@code Method} object that reflects the specified public
jaroslav@56
  1545
     * member method of the class or interface represented by this
jaroslav@56
  1546
     * {@code Class} object. The {@code name} parameter is a
jaroslav@56
  1547
     * {@code String} specifying the simple name of the desired method. The
jaroslav@56
  1548
     * {@code parameterTypes} parameter is an array of {@code Class}
jaroslav@56
  1549
     * objects that identify the method's formal parameter types, in declared
jaroslav@56
  1550
     * order. If {@code parameterTypes} is {@code null}, it is
jaroslav@56
  1551
     * treated as if it were an empty array.
jaroslav@56
  1552
     *
jaroslav@56
  1553
     * <p> If the {@code name} is "{@code <init>};"or "{@code <clinit>}" a
jaroslav@56
  1554
     * {@code NoSuchMethodException} is raised. Otherwise, the method to
jaroslav@56
  1555
     * be reflected is determined by the algorithm that follows.  Let C be the
jaroslav@56
  1556
     * class represented by this object:
jaroslav@56
  1557
     * <OL>
jaroslav@56
  1558
     * <LI> C is searched for any <I>matching methods</I>. If no matching
jaroslav@56
  1559
     *      method is found, the algorithm of step 1 is invoked recursively on
jaroslav@56
  1560
     *      the superclass of C.</LI>
jaroslav@56
  1561
     * <LI> If no method was found in step 1 above, the superinterfaces of C
jaroslav@56
  1562
     *      are searched for a matching method. If any such method is found, it
jaroslav@56
  1563
     *      is reflected.</LI>
jaroslav@56
  1564
     * </OL>
jaroslav@56
  1565
     *
jaroslav@56
  1566
     * To find a matching method in a class C:&nbsp; If C declares exactly one
jaroslav@56
  1567
     * public method with the specified name and exactly the same formal
jaroslav@56
  1568
     * parameter types, that is the method reflected. If more than one such
jaroslav@56
  1569
     * method is found in C, and one of these methods has a return type that is
jaroslav@56
  1570
     * more specific than any of the others, that method is reflected;
jaroslav@56
  1571
     * otherwise one of the methods is chosen arbitrarily.
jaroslav@56
  1572
     *
jaroslav@56
  1573
     * <p>Note that there may be more than one matching method in a
jaroslav@56
  1574
     * class because while the Java language forbids a class to
jaroslav@56
  1575
     * declare multiple methods with the same signature but different
jaroslav@56
  1576
     * return types, the Java virtual machine does not.  This
jaroslav@56
  1577
     * increased flexibility in the virtual machine can be used to
jaroslav@56
  1578
     * implement various language features.  For example, covariant
jaroslav@56
  1579
     * returns can be implemented with {@linkplain
jaroslav@56
  1580
     * java.lang.reflect.Method#isBridge bridge methods}; the bridge
jaroslav@56
  1581
     * method and the method being overridden would have the same
jaroslav@56
  1582
     * signature but different return types.
jaroslav@56
  1583
     *
jaroslav@56
  1584
     * <p> See <em>The Java Language Specification</em>, sections 8.2 and 8.4.
jaroslav@56
  1585
     *
jaroslav@56
  1586
     * @param name the name of the method
jaroslav@56
  1587
     * @param parameterTypes the list of parameters
jaroslav@56
  1588
     * @return the {@code Method} object that matches the specified
jaroslav@56
  1589
     * {@code name} and {@code parameterTypes}
jaroslav@56
  1590
     * @exception NoSuchMethodException if a matching method is not found
jaroslav@56
  1591
     *            or if the name is "&lt;init&gt;"or "&lt;clinit&gt;".
jaroslav@56
  1592
     * @exception NullPointerException if {@code name} is {@code null}
jaroslav@56
  1593
     * @exception  SecurityException
jaroslav@56
  1594
     *             If a security manager, <i>s</i>, is present and any of the
jaroslav@56
  1595
     *             following conditions is met:
jaroslav@56
  1596
     *
jaroslav@56
  1597
     *             <ul>
jaroslav@56
  1598
     *
jaroslav@56
  1599
     *             <li> invocation of
jaroslav@56
  1600
     *             {@link SecurityManager#checkMemberAccess
jaroslav@56
  1601
     *             s.checkMemberAccess(this, Member.PUBLIC)} denies
jaroslav@56
  1602
     *             access to the method
jaroslav@56
  1603
     *
jaroslav@56
  1604
     *             <li> the caller's class loader is not the same as or an
jaroslav@56
  1605
     *             ancestor of the class loader for the current class and
jaroslav@56
  1606
     *             invocation of {@link SecurityManager#checkPackageAccess
jaroslav@56
  1607
     *             s.checkPackageAccess()} denies access to the package
jaroslav@56
  1608
     *             of this class
jaroslav@56
  1609
     *
jaroslav@56
  1610
     *             </ul>
jaroslav@56
  1611
     *
jaroslav@56
  1612
     * @since JDK1.1
jaroslav@56
  1613
     */
jaroslav@56
  1614
    public Method getMethod(String name, Class<?>... parameterTypes)
jaroslav@56
  1615
        throws NoSuchMethodException, SecurityException {
jaroslav@56
  1616
        // be very careful not to change the stack depth of this
jaroslav@56
  1617
        // checkMemberAccess call for security reasons
jaroslav@56
  1618
        // see java.lang.SecurityManager.checkMemberAccess
jaroslav@56
  1619
        checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
jaroslav@56
  1620
        Method method = getMethod0(name, parameterTypes);
jaroslav@56
  1621
        if (method == null) {
jaroslav@56
  1622
            throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
jaroslav@56
  1623
        }
jaroslav@56
  1624
        return method;
jaroslav@56
  1625
    }
jaroslav@56
  1626
jaroslav@56
  1627
jaroslav@56
  1628
    /**
jaroslav@56
  1629
     * Returns a {@code Constructor} object that reflects the specified
jaroslav@56
  1630
     * public constructor of the class represented by this {@code Class}
jaroslav@56
  1631
     * object. The {@code parameterTypes} parameter is an array of
jaroslav@56
  1632
     * {@code Class} objects that identify the constructor's formal
jaroslav@56
  1633
     * parameter types, in declared order.
jaroslav@56
  1634
     *
jaroslav@56
  1635
     * If this {@code Class} object represents an inner class
jaroslav@56
  1636
     * declared in a non-static context, the formal parameter types
jaroslav@56
  1637
     * include the explicit enclosing instance as the first parameter.
jaroslav@56
  1638
     *
jaroslav@56
  1639
     * <p> The constructor to reflect is the public constructor of the class
jaroslav@56
  1640
     * represented by this {@code Class} object whose formal parameter
jaroslav@56
  1641
     * types match those specified by {@code parameterTypes}.
jaroslav@56
  1642
     *
jaroslav@56
  1643
     * @param parameterTypes the parameter array
jaroslav@56
  1644
     * @return the {@code Constructor} object of the public constructor that
jaroslav@56
  1645
     * matches the specified {@code parameterTypes}
jaroslav@56
  1646
     * @exception NoSuchMethodException if a matching method is not found.
jaroslav@56
  1647
     * @exception  SecurityException
jaroslav@56
  1648
     *             If a security manager, <i>s</i>, is present and any of the
jaroslav@56
  1649
     *             following conditions is met:
jaroslav@56
  1650
     *
jaroslav@56
  1651
     *             <ul>
jaroslav@56
  1652
     *
jaroslav@56
  1653
     *             <li> invocation of
jaroslav@56
  1654
     *             {@link SecurityManager#checkMemberAccess
jaroslav@56
  1655
     *             s.checkMemberAccess(this, Member.PUBLIC)} denies
jaroslav@56
  1656
     *             access to the constructor
jaroslav@56
  1657
     *
jaroslav@56
  1658
     *             <li> the caller's class loader is not the same as or an
jaroslav@56
  1659
     *             ancestor of the class loader for the current class and
jaroslav@56
  1660
     *             invocation of {@link SecurityManager#checkPackageAccess
jaroslav@56
  1661
     *             s.checkPackageAccess()} denies access to the package
jaroslav@56
  1662
     *             of this class
jaroslav@56
  1663
     *
jaroslav@56
  1664
     *             </ul>
jaroslav@56
  1665
     *
jaroslav@56
  1666
     * @since JDK1.1
jaroslav@56
  1667
     */
jaroslav@56
  1668
    public Constructor<T> getConstructor(Class<?>... parameterTypes)
jaroslav@56
  1669
        throws NoSuchMethodException, SecurityException {
jaroslav@56
  1670
        // be very careful not to change the stack depth of this
jaroslav@56
  1671
        // checkMemberAccess call for security reasons
jaroslav@56
  1672
        // see java.lang.SecurityManager.checkMemberAccess
jaroslav@56
  1673
        checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
jaroslav@56
  1674
        return getConstructor0(parameterTypes, Member.PUBLIC);
jaroslav@56
  1675
    }
jaroslav@56
  1676
jaroslav@56
  1677
jaroslav@56
  1678
    /**
jaroslav@56
  1679
     * Returns an array of {@code Class} objects reflecting all the
jaroslav@56
  1680
     * classes and interfaces declared as members of the class represented by
jaroslav@56
  1681
     * this {@code Class} object. This includes public, protected, default
jaroslav@56
  1682
     * (package) access, and private classes and interfaces declared by the
jaroslav@56
  1683
     * class, but excludes inherited classes and interfaces.  This method
jaroslav@56
  1684
     * returns an array of length 0 if the class declares no classes or
jaroslav@56
  1685
     * interfaces as members, or if this {@code Class} object represents a
jaroslav@56
  1686
     * primitive type, an array class, or void.
jaroslav@56
  1687
     *
jaroslav@56
  1688
     * @return the array of {@code Class} objects representing all the
jaroslav@56
  1689
     * declared members of this class
jaroslav@56
  1690
     * @exception  SecurityException
jaroslav@56
  1691
     *             If a security manager, <i>s</i>, is present and any of the
jaroslav@56
  1692
     *             following conditions is met:
jaroslav@56
  1693
     *
jaroslav@56
  1694
     *             <ul>
jaroslav@56
  1695
     *
jaroslav@56
  1696
     *             <li> invocation of
jaroslav@56
  1697
     *             {@link SecurityManager#checkMemberAccess
jaroslav@56
  1698
     *             s.checkMemberAccess(this, Member.DECLARED)} denies
jaroslav@56
  1699
     *             access to the declared classes within this class
jaroslav@56
  1700
     *
jaroslav@56
  1701
     *             <li> the caller's class loader is not the same as or an
jaroslav@56
  1702
     *             ancestor of the class loader for the current class and
jaroslav@56
  1703
     *             invocation of {@link SecurityManager#checkPackageAccess
jaroslav@56
  1704
     *             s.checkPackageAccess()} denies access to the package
jaroslav@56
  1705
     *             of this class
jaroslav@56
  1706
     *
jaroslav@56
  1707
     *             </ul>
jaroslav@56
  1708
     *
jaroslav@56
  1709
     * @since JDK1.1
jaroslav@56
  1710
     */
jaroslav@56
  1711
    public Class<?>[] getDeclaredClasses() throws SecurityException {
jaroslav@56
  1712
        // be very careful not to change the stack depth of this
jaroslav@56
  1713
        // checkMemberAccess call for security reasons
jaroslav@56
  1714
        // see java.lang.SecurityManager.checkMemberAccess
jaroslav@56
  1715
        checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
jaroslav@56
  1716
        return getDeclaredClasses0();
jaroslav@56
  1717
    }
jaroslav@56
  1718
jaroslav@56
  1719
jaroslav@56
  1720
    /**
jaroslav@56
  1721
     * Returns an array of {@code Field} objects reflecting all the fields
jaroslav@56
  1722
     * declared by the class or interface represented by this
jaroslav@56
  1723
     * {@code Class} object. This includes public, protected, default
jaroslav@56
  1724
     * (package) access, and private fields, but excludes inherited fields.
jaroslav@56
  1725
     * The elements in the array returned are not sorted and are not in any
jaroslav@56
  1726
     * particular order.  This method returns an array of length 0 if the class
jaroslav@56
  1727
     * or interface declares no fields, or if this {@code Class} object
jaroslav@56
  1728
     * represents a primitive type, an array class, or void.
jaroslav@56
  1729
     *
jaroslav@56
  1730
     * <p> See <em>The Java Language Specification</em>, sections 8.2 and 8.3.
jaroslav@56
  1731
     *
jaroslav@56
  1732
     * @return    the array of {@code Field} objects representing all the
jaroslav@56
  1733
     * declared fields of this class
jaroslav@56
  1734
     * @exception  SecurityException
jaroslav@56
  1735
     *             If a security manager, <i>s</i>, is present and any of the
jaroslav@56
  1736
     *             following conditions is met:
jaroslav@56
  1737
     *
jaroslav@56
  1738
     *             <ul>
jaroslav@56
  1739
     *
jaroslav@56
  1740
     *             <li> invocation of
jaroslav@56
  1741
     *             {@link SecurityManager#checkMemberAccess
jaroslav@56
  1742
     *             s.checkMemberAccess(this, Member.DECLARED)} denies
jaroslav@56
  1743
     *             access to the declared fields within this class
jaroslav@56
  1744
     *
jaroslav@56
  1745
     *             <li> the caller's class loader is not the same as or an
jaroslav@56
  1746
     *             ancestor of the class loader for the current class and
jaroslav@56
  1747
     *             invocation of {@link SecurityManager#checkPackageAccess
jaroslav@56
  1748
     *             s.checkPackageAccess()} denies access to the package
jaroslav@56
  1749
     *             of this class
jaroslav@56
  1750
     *
jaroslav@56
  1751
     *             </ul>
jaroslav@56
  1752
     *
jaroslav@56
  1753
     * @since JDK1.1
jaroslav@56
  1754
     */
jaroslav@56
  1755
    public Field[] getDeclaredFields() throws SecurityException {
jaroslav@56
  1756
        // be very careful not to change the stack depth of this
jaroslav@56
  1757
        // checkMemberAccess call for security reasons
jaroslav@56
  1758
        // see java.lang.SecurityManager.checkMemberAccess
jaroslav@56
  1759
        checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
jaroslav@56
  1760
        return copyFields(privateGetDeclaredFields(false));
jaroslav@56
  1761
    }
jaroslav@56
  1762
jaroslav@56
  1763
jaroslav@56
  1764
    /**
jaroslav@56
  1765
     * Returns an array of {@code Method} objects reflecting all the
jaroslav@56
  1766
     * methods declared by the class or interface represented by this
jaroslav@56
  1767
     * {@code Class} object. This includes public, protected, default
jaroslav@56
  1768
     * (package) access, and private methods, but excludes inherited methods.
jaroslav@56
  1769
     * The elements in the array returned are not sorted and are not in any
jaroslav@56
  1770
     * particular order.  This method returns an array of length 0 if the class
jaroslav@56
  1771
     * or interface declares no methods, or if this {@code Class} object
jaroslav@56
  1772
     * represents a primitive type, an array class, or void.  The class
jaroslav@56
  1773
     * initialization method {@code <clinit>} is not included in the
jaroslav@56
  1774
     * returned array. If the class declares multiple public member methods
jaroslav@56
  1775
     * with the same parameter types, they are all included in the returned
jaroslav@56
  1776
     * array.
jaroslav@56
  1777
     *
jaroslav@56
  1778
     * <p> See <em>The Java Language Specification</em>, section 8.2.
jaroslav@56
  1779
     *
jaroslav@56
  1780
     * @return    the array of {@code Method} objects representing all the
jaroslav@56
  1781
     * declared methods of this class
jaroslav@56
  1782
     * @exception  SecurityException
jaroslav@56
  1783
     *             If a security manager, <i>s</i>, is present and any of the
jaroslav@56
  1784
     *             following conditions is met:
jaroslav@56
  1785
     *
jaroslav@56
  1786
     *             <ul>
jaroslav@56
  1787
     *
jaroslav@56
  1788
     *             <li> invocation of
jaroslav@56
  1789
     *             {@link SecurityManager#checkMemberAccess
jaroslav@56
  1790
     *             s.checkMemberAccess(this, Member.DECLARED)} denies
jaroslav@56
  1791
     *             access to the declared methods within this class
jaroslav@56
  1792
     *
jaroslav@56
  1793
     *             <li> the caller's class loader is not the same as or an
jaroslav@56
  1794
     *             ancestor of the class loader for the current class and
jaroslav@56
  1795
     *             invocation of {@link SecurityManager#checkPackageAccess
jaroslav@56
  1796
     *             s.checkPackageAccess()} denies access to the package
jaroslav@56
  1797
     *             of this class
jaroslav@56
  1798
     *
jaroslav@56
  1799
     *             </ul>
jaroslav@56
  1800
     *
jaroslav@56
  1801
     * @since JDK1.1
jaroslav@56
  1802
     */
jaroslav@56
  1803
    public Method[] getDeclaredMethods() throws SecurityException {
jaroslav@56
  1804
        // be very careful not to change the stack depth of this
jaroslav@56
  1805
        // checkMemberAccess call for security reasons
jaroslav@56
  1806
        // see java.lang.SecurityManager.checkMemberAccess
jaroslav@56
  1807
        checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
jaroslav@56
  1808
        return copyMethods(privateGetDeclaredMethods(false));
jaroslav@56
  1809
    }
jaroslav@56
  1810
jaroslav@56
  1811
jaroslav@56
  1812
    /**
jaroslav@56
  1813
     * Returns an array of {@code Constructor} objects reflecting all the
jaroslav@56
  1814
     * constructors declared by the class represented by this
jaroslav@56
  1815
     * {@code Class} object. These are public, protected, default
jaroslav@56
  1816
     * (package) access, and private constructors.  The elements in the array
jaroslav@56
  1817
     * returned are not sorted and are not in any particular order.  If the
jaroslav@56
  1818
     * class has a default constructor, it is included in the returned array.
jaroslav@56
  1819
     * This method returns an array of length 0 if this {@code Class}
jaroslav@56
  1820
     * object represents an interface, a primitive type, an array class, or
jaroslav@56
  1821
     * void.
jaroslav@56
  1822
     *
jaroslav@56
  1823
     * <p> See <em>The Java Language Specification</em>, section 8.2.
jaroslav@56
  1824
     *
jaroslav@56
  1825
     * @return    the array of {@code Constructor} objects representing all the
jaroslav@56
  1826
     * declared constructors of this class
jaroslav@56
  1827
     * @exception  SecurityException
jaroslav@56
  1828
     *             If a security manager, <i>s</i>, is present and any of the
jaroslav@56
  1829
     *             following conditions is met:
jaroslav@56
  1830
     *
jaroslav@56
  1831
     *             <ul>
jaroslav@56
  1832
     *
jaroslav@56
  1833
     *             <li> invocation of
jaroslav@56
  1834
     *             {@link SecurityManager#checkMemberAccess
jaroslav@56
  1835
     *             s.checkMemberAccess(this, Member.DECLARED)} denies
jaroslav@56
  1836
     *             access to the declared constructors within this class
jaroslav@56
  1837
     *
jaroslav@56
  1838
     *             <li> the caller's class loader is not the same as or an
jaroslav@56
  1839
     *             ancestor of the class loader for the current class and
jaroslav@56
  1840
     *             invocation of {@link SecurityManager#checkPackageAccess
jaroslav@56
  1841
     *             s.checkPackageAccess()} denies access to the package
jaroslav@56
  1842
     *             of this class
jaroslav@56
  1843
     *
jaroslav@56
  1844
     *             </ul>
jaroslav@56
  1845
     *
jaroslav@56
  1846
     * @since JDK1.1
jaroslav@56
  1847
     */
jaroslav@56
  1848
    public Constructor<?>[] getDeclaredConstructors() throws SecurityException {
jaroslav@56
  1849
        // be very careful not to change the stack depth of this
jaroslav@56
  1850
        // checkMemberAccess call for security reasons
jaroslav@56
  1851
        // see java.lang.SecurityManager.checkMemberAccess
jaroslav@56
  1852
        checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
jaroslav@56
  1853
        return copyConstructors(privateGetDeclaredConstructors(false));
jaroslav@56
  1854
    }
jaroslav@56
  1855
jaroslav@56
  1856
jaroslav@56
  1857
    /**
jaroslav@56
  1858
     * Returns a {@code Field} object that reflects the specified declared
jaroslav@56
  1859
     * field of the class or interface represented by this {@code Class}
jaroslav@56
  1860
     * object. The {@code name} parameter is a {@code String} that
jaroslav@56
  1861
     * specifies the simple name of the desired field.  Note that this method
jaroslav@56
  1862
     * will not reflect the {@code length} field of an array class.
jaroslav@56
  1863
     *
jaroslav@56
  1864
     * @param name the name of the field
jaroslav@56
  1865
     * @return the {@code Field} object for the specified field in this
jaroslav@56
  1866
     * class
jaroslav@56
  1867
     * @exception NoSuchFieldException if a field with the specified name is
jaroslav@56
  1868
     *              not found.
jaroslav@56
  1869
     * @exception NullPointerException if {@code name} is {@code null}
jaroslav@56
  1870
     * @exception  SecurityException
jaroslav@56
  1871
     *             If a security manager, <i>s</i>, is present and any of the
jaroslav@56
  1872
     *             following conditions is met:
jaroslav@56
  1873
     *
jaroslav@56
  1874
     *             <ul>
jaroslav@56
  1875
     *
jaroslav@56
  1876
     *             <li> invocation of
jaroslav@56
  1877
     *             {@link SecurityManager#checkMemberAccess
jaroslav@56
  1878
     *             s.checkMemberAccess(this, Member.DECLARED)} denies
jaroslav@56
  1879
     *             access to the declared field
jaroslav@56
  1880
     *
jaroslav@56
  1881
     *             <li> the caller's class loader is not the same as or an
jaroslav@56
  1882
     *             ancestor of the class loader for the current class and
jaroslav@56
  1883
     *             invocation of {@link SecurityManager#checkPackageAccess
jaroslav@56
  1884
     *             s.checkPackageAccess()} denies access to the package
jaroslav@56
  1885
     *             of this class
jaroslav@56
  1886
     *
jaroslav@56
  1887
     *             </ul>
jaroslav@56
  1888
     *
jaroslav@56
  1889
     * @since JDK1.1
jaroslav@56
  1890
     */
jaroslav@56
  1891
    public Field getDeclaredField(String name)
jaroslav@56
  1892
        throws NoSuchFieldException, SecurityException {
jaroslav@56
  1893
        // be very careful not to change the stack depth of this
jaroslav@56
  1894
        // checkMemberAccess call for security reasons
jaroslav@56
  1895
        // see java.lang.SecurityManager.checkMemberAccess
jaroslav@56
  1896
        checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
jaroslav@56
  1897
        Field field = searchFields(privateGetDeclaredFields(false), name);
jaroslav@56
  1898
        if (field == null) {
jaroslav@56
  1899
            throw new NoSuchFieldException(name);
jaroslav@56
  1900
        }
jaroslav@56
  1901
        return field;
jaroslav@56
  1902
    }
jaroslav@56
  1903
jaroslav@56
  1904
jaroslav@56
  1905
    /**
jaroslav@56
  1906
     * Returns a {@code Method} object that reflects the specified
jaroslav@56
  1907
     * declared method of the class or interface represented by this
jaroslav@56
  1908
     * {@code Class} object. The {@code name} parameter is a
jaroslav@56
  1909
     * {@code String} that specifies the simple name of the desired
jaroslav@56
  1910
     * method, and the {@code parameterTypes} parameter is an array of
jaroslav@56
  1911
     * {@code Class} objects that identify the method's formal parameter
jaroslav@56
  1912
     * types, in declared order.  If more than one method with the same
jaroslav@56
  1913
     * parameter types is declared in a class, and one of these methods has a
jaroslav@56
  1914
     * return type that is more specific than any of the others, that method is
jaroslav@56
  1915
     * returned; otherwise one of the methods is chosen arbitrarily.  If the
jaroslav@56
  1916
     * name is "&lt;init&gt;"or "&lt;clinit&gt;" a {@code NoSuchMethodException}
jaroslav@56
  1917
     * is raised.
jaroslav@56
  1918
     *
jaroslav@56
  1919
     * @param name the name of the method
jaroslav@56
  1920
     * @param parameterTypes the parameter array
jaroslav@56
  1921
     * @return    the {@code Method} object for the method of this class
jaroslav@56
  1922
     * matching the specified name and parameters
jaroslav@56
  1923
     * @exception NoSuchMethodException if a matching method is not found.
jaroslav@56
  1924
     * @exception NullPointerException if {@code name} is {@code null}
jaroslav@56
  1925
     * @exception  SecurityException
jaroslav@56
  1926
     *             If a security manager, <i>s</i>, is present and any of the
jaroslav@56
  1927
     *             following conditions is met:
jaroslav@56
  1928
     *
jaroslav@56
  1929
     *             <ul>
jaroslav@56
  1930
     *
jaroslav@56
  1931
     *             <li> invocation of
jaroslav@56
  1932
     *             {@link SecurityManager#checkMemberAccess
jaroslav@56
  1933
     *             s.checkMemberAccess(this, Member.DECLARED)} denies
jaroslav@56
  1934
     *             access to the declared method
jaroslav@56
  1935
     *
jaroslav@56
  1936
     *             <li> the caller's class loader is not the same as or an
jaroslav@56
  1937
     *             ancestor of the class loader for the current class and
jaroslav@56
  1938
     *             invocation of {@link SecurityManager#checkPackageAccess
jaroslav@56
  1939
     *             s.checkPackageAccess()} denies access to the package
jaroslav@56
  1940
     *             of this class
jaroslav@56
  1941
     *
jaroslav@56
  1942
     *             </ul>
jaroslav@56
  1943
     *
jaroslav@56
  1944
     * @since JDK1.1
jaroslav@56
  1945
     */
jaroslav@56
  1946
    public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
jaroslav@56
  1947
        throws NoSuchMethodException, SecurityException {
jaroslav@56
  1948
        // be very careful not to change the stack depth of this
jaroslav@56
  1949
        // checkMemberAccess call for security reasons
jaroslav@56
  1950
        // see java.lang.SecurityManager.checkMemberAccess
jaroslav@56
  1951
        checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
jaroslav@56
  1952
        Method method = searchMethods(privateGetDeclaredMethods(false), name, parameterTypes);
jaroslav@56
  1953
        if (method == null) {
jaroslav@56
  1954
            throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
jaroslav@56
  1955
        }
jaroslav@56
  1956
        return method;
jaroslav@56
  1957
    }
jaroslav@56
  1958
jaroslav@56
  1959
jaroslav@56
  1960
    /**
jaroslav@56
  1961
     * Returns a {@code Constructor} object that reflects the specified
jaroslav@56
  1962
     * constructor of the class or interface represented by this
jaroslav@56
  1963
     * {@code Class} object.  The {@code parameterTypes} parameter is
jaroslav@56
  1964
     * an array of {@code Class} objects that identify the constructor's
jaroslav@56
  1965
     * formal parameter types, in declared order.
jaroslav@56
  1966
     *
jaroslav@56
  1967
     * If this {@code Class} object represents an inner class
jaroslav@56
  1968
     * declared in a non-static context, the formal parameter types
jaroslav@56
  1969
     * include the explicit enclosing instance as the first parameter.
jaroslav@56
  1970
     *
jaroslav@56
  1971
     * @param parameterTypes the parameter array
jaroslav@56
  1972
     * @return    The {@code Constructor} object for the constructor with the
jaroslav@56
  1973
     * specified parameter list
jaroslav@56
  1974
     * @exception NoSuchMethodException if a matching method is not found.
jaroslav@56
  1975
     * @exception  SecurityException
jaroslav@56
  1976
     *             If a security manager, <i>s</i>, is present and any of the
jaroslav@56
  1977
     *             following conditions is met:
jaroslav@56
  1978
     *
jaroslav@56
  1979
     *             <ul>
jaroslav@56
  1980
     *
jaroslav@56
  1981
     *             <li> invocation of
jaroslav@56
  1982
     *             {@link SecurityManager#checkMemberAccess
jaroslav@56
  1983
     *             s.checkMemberAccess(this, Member.DECLARED)} denies
jaroslav@56
  1984
     *             access to the declared constructor
jaroslav@56
  1985
     *
jaroslav@56
  1986
     *             <li> the caller's class loader is not the same as or an
jaroslav@56
  1987
     *             ancestor of the class loader for the current class and
jaroslav@56
  1988
     *             invocation of {@link SecurityManager#checkPackageAccess
jaroslav@56
  1989
     *             s.checkPackageAccess()} denies access to the package
jaroslav@56
  1990
     *             of this class
jaroslav@56
  1991
     *
jaroslav@56
  1992
     *             </ul>
jaroslav@56
  1993
     *
jaroslav@56
  1994
     * @since JDK1.1
jaroslav@56
  1995
     */
jaroslav@56
  1996
    public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
jaroslav@56
  1997
        throws NoSuchMethodException, SecurityException {
jaroslav@56
  1998
        // be very careful not to change the stack depth of this
jaroslav@56
  1999
        // checkMemberAccess call for security reasons
jaroslav@56
  2000
        // see java.lang.SecurityManager.checkMemberAccess
jaroslav@56
  2001
        checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
jaroslav@56
  2002
        return getConstructor0(parameterTypes, Member.DECLARED);
jaroslav@56
  2003
    }
jaroslav@56
  2004
jaroslav@56
  2005
    /**
jaroslav@56
  2006
     * Finds a resource with a given name.  The rules for searching resources
jaroslav@56
  2007
     * associated with a given class are implemented by the defining
jaroslav@56
  2008
     * {@linkplain ClassLoader class loader} of the class.  This method
jaroslav@56
  2009
     * delegates to this object's class loader.  If this object was loaded by
jaroslav@56
  2010
     * the bootstrap class loader, the method delegates to {@link
jaroslav@56
  2011
     * ClassLoader#getSystemResourceAsStream}.
jaroslav@56
  2012
     *
jaroslav@56
  2013
     * <p> Before delegation, an absolute resource name is constructed from the
jaroslav@56
  2014
     * given resource name using this algorithm:
jaroslav@56
  2015
     *
jaroslav@56
  2016
     * <ul>
jaroslav@56
  2017
     *
jaroslav@56
  2018
     * <li> If the {@code name} begins with a {@code '/'}
jaroslav@56
  2019
     * (<tt>'&#92;u002f'</tt>), then the absolute name of the resource is the
jaroslav@56
  2020
     * portion of the {@code name} following the {@code '/'}.
jaroslav@56
  2021
     *
jaroslav@56
  2022
     * <li> Otherwise, the absolute name is of the following form:
jaroslav@56
  2023
     *
jaroslav@56
  2024
     * <blockquote>
jaroslav@56
  2025
     *   {@code modified_package_name/name}
jaroslav@56
  2026
     * </blockquote>
jaroslav@56
  2027
     *
jaroslav@56
  2028
     * <p> Where the {@code modified_package_name} is the package name of this
jaroslav@56
  2029
     * object with {@code '/'} substituted for {@code '.'}
jaroslav@56
  2030
     * (<tt>'&#92;u002e'</tt>).
jaroslav@56
  2031
     *
jaroslav@56
  2032
     * </ul>
jaroslav@56
  2033
     *
jaroslav@56
  2034
     * @param  name name of the desired resource
jaroslav@56
  2035
     * @return      A {@link java.io.InputStream} object or {@code null} if
jaroslav@56
  2036
     *              no resource with this name is found
jaroslav@56
  2037
     * @throws  NullPointerException If {@code name} is {@code null}
jaroslav@56
  2038
     * @since  JDK1.1
jaroslav@56
  2039
     */
jaroslav@56
  2040
     public InputStream getResourceAsStream(String name) {
jaroslav@56
  2041
        name = resolveName(name);
jaroslav@56
  2042
        ClassLoader cl = getClassLoader0();
jaroslav@56
  2043
        if (cl==null) {
jaroslav@56
  2044
            // A system class.
jaroslav@56
  2045
            return ClassLoader.getSystemResourceAsStream(name);
jaroslav@56
  2046
        }
jaroslav@56
  2047
        return cl.getResourceAsStream(name);
jaroslav@56
  2048
    }
jaroslav@56
  2049
jaroslav@56
  2050
    /**
jaroslav@56
  2051
     * Finds a resource with a given name.  The rules for searching resources
jaroslav@56
  2052
     * associated with a given class are implemented by the defining
jaroslav@56
  2053
     * {@linkplain ClassLoader class loader} of the class.  This method
jaroslav@56
  2054
     * delegates to this object's class loader.  If this object was loaded by
jaroslav@56
  2055
     * the bootstrap class loader, the method delegates to {@link
jaroslav@56
  2056
     * ClassLoader#getSystemResource}.
jaroslav@56
  2057
     *
jaroslav@56
  2058
     * <p> Before delegation, an absolute resource name is constructed from the
jaroslav@56
  2059
     * given resource name using this algorithm:
jaroslav@56
  2060
     *
jaroslav@56
  2061
     * <ul>
jaroslav@56
  2062
     *
jaroslav@56
  2063
     * <li> If the {@code name} begins with a {@code '/'}
jaroslav@56
  2064
     * (<tt>'&#92;u002f'</tt>), then the absolute name of the resource is the
jaroslav@56
  2065
     * portion of the {@code name} following the {@code '/'}.
jaroslav@56
  2066
     *
jaroslav@56
  2067
     * <li> Otherwise, the absolute name is of the following form:
jaroslav@56
  2068
     *
jaroslav@56
  2069
     * <blockquote>
jaroslav@56
  2070
     *   {@code modified_package_name/name}
jaroslav@56
  2071
     * </blockquote>
jaroslav@56
  2072
     *
jaroslav@56
  2073
     * <p> Where the {@code modified_package_name} is the package name of this
jaroslav@56
  2074
     * object with {@code '/'} substituted for {@code '.'}
jaroslav@56
  2075
     * (<tt>'&#92;u002e'</tt>).
jaroslav@56
  2076
     *
jaroslav@56
  2077
     * </ul>
jaroslav@56
  2078
     *
jaroslav@56
  2079
     * @param  name name of the desired resource
jaroslav@56
  2080
     * @return      A  {@link java.net.URL} object or {@code null} if no
jaroslav@56
  2081
     *              resource with this name is found
jaroslav@56
  2082
     * @since  JDK1.1
jaroslav@56
  2083
     */
jaroslav@56
  2084
    public java.net.URL getResource(String name) {
jaroslav@56
  2085
        name = resolveName(name);
jaroslav@56
  2086
        ClassLoader cl = getClassLoader0();
jaroslav@56
  2087
        if (cl==null) {
jaroslav@56
  2088
            // A system class.
jaroslav@56
  2089
            return ClassLoader.getSystemResource(name);
jaroslav@56
  2090
        }
jaroslav@56
  2091
        return cl.getResource(name);
jaroslav@56
  2092
    }
jaroslav@56
  2093
jaroslav@56
  2094
jaroslav@56
  2095
jaroslav@56
  2096
    /** protection domain returned when the internal domain is null */
jaroslav@56
  2097
    private static java.security.ProtectionDomain allPermDomain;
jaroslav@56
  2098
jaroslav@56
  2099
jaroslav@56
  2100
    /**
jaroslav@56
  2101
     * Returns the {@code ProtectionDomain} of this class.  If there is a
jaroslav@56
  2102
     * security manager installed, this method first calls the security
jaroslav@56
  2103
     * manager's {@code checkPermission} method with a
jaroslav@56
  2104
     * {@code RuntimePermission("getProtectionDomain")} permission to
jaroslav@56
  2105
     * ensure it's ok to get the
jaroslav@56
  2106
     * {@code ProtectionDomain}.
jaroslav@56
  2107
     *
jaroslav@56
  2108
     * @return the ProtectionDomain of this class
jaroslav@56
  2109
     *
jaroslav@56
  2110
     * @throws SecurityException
jaroslav@56
  2111
     *        if a security manager exists and its
jaroslav@56
  2112
     *        {@code checkPermission} method doesn't allow
jaroslav@56
  2113
     *        getting the ProtectionDomain.
jaroslav@56
  2114
     *
jaroslav@56
  2115
     * @see java.security.ProtectionDomain
jaroslav@56
  2116
     * @see SecurityManager#checkPermission
jaroslav@56
  2117
     * @see java.lang.RuntimePermission
jaroslav@56
  2118
     * @since 1.2
jaroslav@56
  2119
     */
jaroslav@56
  2120
    public java.security.ProtectionDomain getProtectionDomain() {
jaroslav@56
  2121
        SecurityManager sm = System.getSecurityManager();
jaroslav@56
  2122
        if (sm != null) {
jaroslav@56
  2123
            sm.checkPermission(SecurityConstants.GET_PD_PERMISSION);
jaroslav@56
  2124
        }
jaroslav@56
  2125
        java.security.ProtectionDomain pd = getProtectionDomain0();
jaroslav@56
  2126
        if (pd == null) {
jaroslav@56
  2127
            if (allPermDomain == null) {
jaroslav@56
  2128
                java.security.Permissions perms =
jaroslav@56
  2129
                    new java.security.Permissions();
jaroslav@56
  2130
                perms.add(SecurityConstants.ALL_PERMISSION);
jaroslav@56
  2131
                allPermDomain =
jaroslav@56
  2132
                    new java.security.ProtectionDomain(null, perms);
jaroslav@56
  2133
            }
jaroslav@56
  2134
            pd = allPermDomain;
jaroslav@56
  2135
        }
jaroslav@56
  2136
        return pd;
jaroslav@56
  2137
    }
jaroslav@56
  2138
jaroslav@56
  2139
jaroslav@56
  2140
    /**
jaroslav@56
  2141
     * Returns the ProtectionDomain of this class.
jaroslav@56
  2142
     */
jaroslav@56
  2143
    private native java.security.ProtectionDomain getProtectionDomain0();
jaroslav@56
  2144
jaroslav@56
  2145
jaroslav@56
  2146
    /**
jaroslav@56
  2147
     * Set the ProtectionDomain for this class. Called by
jaroslav@56
  2148
     * ClassLoader.defineClass.
jaroslav@56
  2149
     */
jaroslav@56
  2150
    native void setProtectionDomain0(java.security.ProtectionDomain pd);
jaroslav@56
  2151
jaroslav@56
  2152
jaroslav@56
  2153
    /*
jaroslav@56
  2154
     * Return the Virtual Machine's Class object for the named
jaroslav@56
  2155
     * primitive type.
jaroslav@56
  2156
     */
jaroslav@56
  2157
    static native Class getPrimitiveClass(String name);
jaroslav@56
  2158
jaroslav@56
  2159
jaroslav@56
  2160
    /*
jaroslav@56
  2161
     * Check if client is allowed to access members.  If access is denied,
jaroslav@56
  2162
     * throw a SecurityException.
jaroslav@56
  2163
     *
jaroslav@56
  2164
     * Be very careful not to change the stack depth of this checkMemberAccess
jaroslav@56
  2165
     * call for security reasons.
jaroslav@56
  2166
     * See java.lang.SecurityManager.checkMemberAccess.
jaroslav@56
  2167
     *
jaroslav@56
  2168
     * <p> Default policy: allow all clients access with normal Java access
jaroslav@56
  2169
     * control.
jaroslav@56
  2170
     */
jaroslav@56
  2171
    private void checkMemberAccess(int which, ClassLoader ccl) {
jaroslav@56
  2172
        SecurityManager s = System.getSecurityManager();
jaroslav@56
  2173
        if (s != null) {
jaroslav@56
  2174
            s.checkMemberAccess(this, which);
jaroslav@56
  2175
            ClassLoader cl = getClassLoader0();
jaroslav@56
  2176
            if ((ccl != null) && (ccl != cl) &&
jaroslav@56
  2177
                  ((cl == null) || !cl.isAncestor(ccl))) {
jaroslav@56
  2178
                String name = this.getName();
jaroslav@56
  2179
                int i = name.lastIndexOf('.');
jaroslav@56
  2180
                if (i != -1) {
jaroslav@56
  2181
                    s.checkPackageAccess(name.substring(0, i));
jaroslav@56
  2182
                }
jaroslav@56
  2183
            }
jaroslav@56
  2184
        }
jaroslav@56
  2185
    }
jaroslav@56
  2186
jaroslav@56
  2187
    /**
jaroslav@56
  2188
     * Add a package name prefix if the name is not absolute Remove leading "/"
jaroslav@56
  2189
     * if name is absolute
jaroslav@56
  2190
     */
jaroslav@56
  2191
    private String resolveName(String name) {
jaroslav@56
  2192
        if (name == null) {
jaroslav@56
  2193
            return name;
jaroslav@56
  2194
        }
jaroslav@56
  2195
        if (!name.startsWith("/")) {
jaroslav@56
  2196
            Class<?> c = this;
jaroslav@56
  2197
            while (c.isArray()) {
jaroslav@56
  2198
                c = c.getComponentType();
jaroslav@56
  2199
            }
jaroslav@56
  2200
            String baseName = c.getName();
jaroslav@56
  2201
            int index = baseName.lastIndexOf('.');
jaroslav@56
  2202
            if (index != -1) {
jaroslav@56
  2203
                name = baseName.substring(0, index).replace('.', '/')
jaroslav@56
  2204
                    +"/"+name;
jaroslav@56
  2205
            }
jaroslav@56
  2206
        } else {
jaroslav@56
  2207
            name = name.substring(1);
jaroslav@56
  2208
        }
jaroslav@56
  2209
        return name;
jaroslav@56
  2210
    }
jaroslav@56
  2211
jaroslav@56
  2212
    /**
jaroslav@56
  2213
     * Reflection support.
jaroslav@56
  2214
     */
jaroslav@56
  2215
jaroslav@56
  2216
    // Caches for certain reflective results
jaroslav@56
  2217
    private static boolean useCaches = true;
jaroslav@56
  2218
    private volatile transient SoftReference<Field[]> declaredFields;
jaroslav@56
  2219
    private volatile transient SoftReference<Field[]> publicFields;
jaroslav@56
  2220
    private volatile transient SoftReference<Method[]> declaredMethods;
jaroslav@56
  2221
    private volatile transient SoftReference<Method[]> publicMethods;
jaroslav@56
  2222
    private volatile transient SoftReference<Constructor<T>[]> declaredConstructors;
jaroslav@56
  2223
    private volatile transient SoftReference<Constructor<T>[]> publicConstructors;
jaroslav@56
  2224
    // Intermediate results for getFields and getMethods
jaroslav@56
  2225
    private volatile transient SoftReference<Field[]> declaredPublicFields;
jaroslav@56
  2226
    private volatile transient SoftReference<Method[]> declaredPublicMethods;
jaroslav@56
  2227
jaroslav@56
  2228
    // Incremented by the VM on each call to JVM TI RedefineClasses()
jaroslav@56
  2229
    // that redefines this class or a superclass.
jaroslav@56
  2230
    private volatile transient int classRedefinedCount = 0;
jaroslav@56
  2231
jaroslav@56
  2232
    // Value of classRedefinedCount when we last cleared the cached values
jaroslav@56
  2233
    // that are sensitive to class redefinition.
jaroslav@56
  2234
    private volatile transient int lastRedefinedCount = 0;
jaroslav@56
  2235
jaroslav@56
  2236
    // Clears cached values that might possibly have been obsoleted by
jaroslav@56
  2237
    // a class redefinition.
jaroslav@56
  2238
    private void clearCachesOnClassRedefinition() {
jaroslav@56
  2239
        if (lastRedefinedCount != classRedefinedCount) {
jaroslav@56
  2240
            declaredFields = publicFields = declaredPublicFields = null;
jaroslav@56
  2241
            declaredMethods = publicMethods = declaredPublicMethods = null;
jaroslav@56
  2242
            declaredConstructors = publicConstructors = null;
jaroslav@56
  2243
            annotations = declaredAnnotations = null;
jaroslav@56
  2244
jaroslav@56
  2245
            // Use of "volatile" (and synchronization by caller in the case
jaroslav@56
  2246
            // of annotations) ensures that no thread sees the update to
jaroslav@56
  2247
            // lastRedefinedCount before seeing the caches cleared.
jaroslav@56
  2248
            // We do not guard against brief windows during which multiple
jaroslav@56
  2249
            // threads might redundantly work to fill an empty cache.
jaroslav@56
  2250
            lastRedefinedCount = classRedefinedCount;
jaroslav@56
  2251
        }
jaroslav@56
  2252
    }
jaroslav@56
  2253
jaroslav@56
  2254
    // Generic signature handling
jaroslav@56
  2255
    private native String getGenericSignature();
jaroslav@56
  2256
jaroslav@56
  2257
    // Generic info repository; lazily initialized
jaroslav@56
  2258
    private transient ClassRepository genericInfo;
jaroslav@56
  2259
jaroslav@56
  2260
    // accessor for factory
jaroslav@56
  2261
    private GenericsFactory getFactory() {
jaroslav@56
  2262
        // create scope and factory
jaroslav@56
  2263
        return CoreReflectionFactory.make(this, ClassScope.make(this));
jaroslav@56
  2264
    }
jaroslav@56
  2265
jaroslav@56
  2266
    // accessor for generic info repository
jaroslav@56
  2267
    private ClassRepository getGenericInfo() {
jaroslav@56
  2268
        // lazily initialize repository if necessary
jaroslav@56
  2269
        if (genericInfo == null) {
jaroslav@56
  2270
            // create and cache generic info repository
jaroslav@56
  2271
            genericInfo = ClassRepository.make(getGenericSignature(),
jaroslav@56
  2272
                                               getFactory());
jaroslav@56
  2273
        }
jaroslav@56
  2274
        return genericInfo; //return cached repository
jaroslav@56
  2275
    }
jaroslav@56
  2276
jaroslav@56
  2277
    // Annotations handling
jaroslav@56
  2278
    private native byte[] getRawAnnotations();
jaroslav@56
  2279
jaroslav@56
  2280
    native ConstantPool getConstantPool();
jaroslav@56
  2281
jaroslav@56
  2282
    //
jaroslav@56
  2283
    //
jaroslav@56
  2284
    // java.lang.reflect.Field handling
jaroslav@56
  2285
    //
jaroslav@56
  2286
    //
jaroslav@56
  2287
jaroslav@56
  2288
    // Returns an array of "root" fields. These Field objects must NOT
jaroslav@56
  2289
    // be propagated to the outside world, but must instead be copied
jaroslav@56
  2290
    // via ReflectionFactory.copyField.
jaroslav@56
  2291
    private Field[] privateGetDeclaredFields(boolean publicOnly) {
jaroslav@56
  2292
        checkInitted();
jaroslav@56
  2293
        Field[] res = null;
jaroslav@56
  2294
        if (useCaches) {
jaroslav@56
  2295
            clearCachesOnClassRedefinition();
jaroslav@56
  2296
            if (publicOnly) {
jaroslav@56
  2297
                if (declaredPublicFields != null) {
jaroslav@56
  2298
                    res = declaredPublicFields.get();
jaroslav@56
  2299
                }
jaroslav@56
  2300
            } else {
jaroslav@56
  2301
                if (declaredFields != null) {
jaroslav@56
  2302
                    res = declaredFields.get();
jaroslav@56
  2303
                }
jaroslav@56
  2304
            }
jaroslav@56
  2305
            if (res != null) return res;
jaroslav@56
  2306
        }
jaroslav@56
  2307
        // No cached value available; request value from VM
jaroslav@56
  2308
        res = Reflection.filterFields(this, getDeclaredFields0(publicOnly));
jaroslav@56
  2309
        if (useCaches) {
jaroslav@56
  2310
            if (publicOnly) {
jaroslav@56
  2311
                declaredPublicFields = new SoftReference<>(res);
jaroslav@56
  2312
            } else {
jaroslav@56
  2313
                declaredFields = new SoftReference<>(res);
jaroslav@56
  2314
            }
jaroslav@56
  2315
        }
jaroslav@56
  2316
        return res;
jaroslav@56
  2317
    }
jaroslav@56
  2318
jaroslav@56
  2319
    // Returns an array of "root" fields. These Field objects must NOT
jaroslav@56
  2320
    // be propagated to the outside world, but must instead be copied
jaroslav@56
  2321
    // via ReflectionFactory.copyField.
jaroslav@56
  2322
    private Field[] privateGetPublicFields(Set<Class<?>> traversedInterfaces) {
jaroslav@56
  2323
        checkInitted();
jaroslav@56
  2324
        Field[] res = null;
jaroslav@56
  2325
        if (useCaches) {
jaroslav@56
  2326
            clearCachesOnClassRedefinition();
jaroslav@56
  2327
            if (publicFields != null) {
jaroslav@56
  2328
                res = publicFields.get();
jaroslav@56
  2329
            }
jaroslav@56
  2330
            if (res != null) return res;
jaroslav@56
  2331
        }
jaroslav@56
  2332
jaroslav@56
  2333
        // No cached value available; compute value recursively.
jaroslav@56
  2334
        // Traverse in correct order for getField().
jaroslav@56
  2335
        List<Field> fields = new ArrayList<>();
jaroslav@56
  2336
        if (traversedInterfaces == null) {
jaroslav@56
  2337
            traversedInterfaces = new HashSet<>();
jaroslav@56
  2338
        }
jaroslav@56
  2339
jaroslav@56
  2340
        // Local fields
jaroslav@56
  2341
        Field[] tmp = privateGetDeclaredFields(true);
jaroslav@56
  2342
        addAll(fields, tmp);
jaroslav@56
  2343
jaroslav@56
  2344
        // Direct superinterfaces, recursively
jaroslav@56
  2345
        for (Class<?> c : getInterfaces()) {
jaroslav@56
  2346
            if (!traversedInterfaces.contains(c)) {
jaroslav@56
  2347
                traversedInterfaces.add(c);
jaroslav@56
  2348
                addAll(fields, c.privateGetPublicFields(traversedInterfaces));
jaroslav@56
  2349
            }
jaroslav@56
  2350
        }
jaroslav@56
  2351
jaroslav@56
  2352
        // Direct superclass, recursively
jaroslav@56
  2353
        if (!isInterface()) {
jaroslav@56
  2354
            Class<?> c = getSuperclass();
jaroslav@56
  2355
            if (c != null) {
jaroslav@56
  2356
                addAll(fields, c.privateGetPublicFields(traversedInterfaces));
jaroslav@56
  2357
            }
jaroslav@56
  2358
        }
jaroslav@56
  2359
jaroslav@56
  2360
        res = new Field[fields.size()];
jaroslav@56
  2361
        fields.toArray(res);
jaroslav@56
  2362
        if (useCaches) {
jaroslav@56
  2363
            publicFields = new SoftReference<>(res);
jaroslav@56
  2364
        }
jaroslav@56
  2365
        return res;
jaroslav@56
  2366
    }
jaroslav@56
  2367
jaroslav@56
  2368
    private static void addAll(Collection<Field> c, Field[] o) {
jaroslav@56
  2369
        for (int i = 0; i < o.length; i++) {
jaroslav@56
  2370
            c.add(o[i]);
jaroslav@56
  2371
        }
jaroslav@56
  2372
    }
jaroslav@56
  2373
jaroslav@56
  2374
jaroslav@56
  2375
    //
jaroslav@56
  2376
    //
jaroslav@56
  2377
    // java.lang.reflect.Constructor handling
jaroslav@56
  2378
    //
jaroslav@56
  2379
    //
jaroslav@56
  2380
jaroslav@56
  2381
    // Returns an array of "root" constructors. These Constructor
jaroslav@56
  2382
    // objects must NOT be propagated to the outside world, but must
jaroslav@56
  2383
    // instead be copied via ReflectionFactory.copyConstructor.
jaroslav@56
  2384
    private Constructor<T>[] privateGetDeclaredConstructors(boolean publicOnly) {
jaroslav@56
  2385
        checkInitted();
jaroslav@56
  2386
        Constructor<T>[] res = null;
jaroslav@56
  2387
        if (useCaches) {
jaroslav@56
  2388
            clearCachesOnClassRedefinition();
jaroslav@56
  2389
            if (publicOnly) {
jaroslav@56
  2390
                if (publicConstructors != null) {
jaroslav@56
  2391
                    res = publicConstructors.get();
jaroslav@56
  2392
                }
jaroslav@56
  2393
            } else {
jaroslav@56
  2394
                if (declaredConstructors != null) {
jaroslav@56
  2395
                    res = declaredConstructors.get();
jaroslav@56
  2396
                }
jaroslav@56
  2397
            }
jaroslav@56
  2398
            if (res != null) return res;
jaroslav@56
  2399
        }
jaroslav@56
  2400
        // No cached value available; request value from VM
jaroslav@56
  2401
        if (isInterface()) {
jaroslav@56
  2402
            res = new Constructor[0];
jaroslav@56
  2403
        } else {
jaroslav@56
  2404
            res = getDeclaredConstructors0(publicOnly);
jaroslav@56
  2405
        }
jaroslav@56
  2406
        if (useCaches) {
jaroslav@56
  2407
            if (publicOnly) {
jaroslav@56
  2408
                publicConstructors = new SoftReference<>(res);
jaroslav@56
  2409
            } else {
jaroslav@56
  2410
                declaredConstructors = new SoftReference<>(res);
jaroslav@56
  2411
            }
jaroslav@56
  2412
        }
jaroslav@56
  2413
        return res;
jaroslav@56
  2414
    }
jaroslav@56
  2415
jaroslav@56
  2416
    //
jaroslav@56
  2417
    //
jaroslav@56
  2418
    // java.lang.reflect.Method handling
jaroslav@56
  2419
    //
jaroslav@56
  2420
    //
jaroslav@56
  2421
jaroslav@56
  2422
    // Returns an array of "root" methods. These Method objects must NOT
jaroslav@56
  2423
    // be propagated to the outside world, but must instead be copied
jaroslav@56
  2424
    // via ReflectionFactory.copyMethod.
jaroslav@56
  2425
    private Method[] privateGetDeclaredMethods(boolean publicOnly) {
jaroslav@56
  2426
        checkInitted();
jaroslav@56
  2427
        Method[] res = null;
jaroslav@56
  2428
        if (useCaches) {
jaroslav@56
  2429
            clearCachesOnClassRedefinition();
jaroslav@56
  2430
            if (publicOnly) {
jaroslav@56
  2431
                if (declaredPublicMethods != null) {
jaroslav@56
  2432
                    res = declaredPublicMethods.get();
jaroslav@56
  2433
                }
jaroslav@56
  2434
            } else {
jaroslav@56
  2435
                if (declaredMethods != null) {
jaroslav@56
  2436
                    res = declaredMethods.get();
jaroslav@56
  2437
                }
jaroslav@56
  2438
            }
jaroslav@56
  2439
            if (res != null) return res;
jaroslav@56
  2440
        }
jaroslav@56
  2441
        // No cached value available; request value from VM
jaroslav@56
  2442
        res = Reflection.filterMethods(this, getDeclaredMethods0(publicOnly));
jaroslav@56
  2443
        if (useCaches) {
jaroslav@56
  2444
            if (publicOnly) {
jaroslav@56
  2445
                declaredPublicMethods = new SoftReference<>(res);
jaroslav@56
  2446
            } else {
jaroslav@56
  2447
                declaredMethods = new SoftReference<>(res);
jaroslav@56
  2448
            }
jaroslav@56
  2449
        }
jaroslav@56
  2450
        return res;
jaroslav@56
  2451
    }
jaroslav@56
  2452
jaroslav@56
  2453
    static class MethodArray {
jaroslav@56
  2454
        private Method[] methods;
jaroslav@56
  2455
        private int length;
jaroslav@56
  2456
jaroslav@56
  2457
        MethodArray() {
jaroslav@56
  2458
            methods = new Method[20];
jaroslav@56
  2459
            length = 0;
jaroslav@56
  2460
        }
jaroslav@56
  2461
jaroslav@56
  2462
        void add(Method m) {
jaroslav@56
  2463
            if (length == methods.length) {
jaroslav@56
  2464
                methods = Arrays.copyOf(methods, 2 * methods.length);
jaroslav@56
  2465
            }
jaroslav@56
  2466
            methods[length++] = m;
jaroslav@56
  2467
        }
jaroslav@56
  2468
jaroslav@56
  2469
        void addAll(Method[] ma) {
jaroslav@56
  2470
            for (int i = 0; i < ma.length; i++) {
jaroslav@56
  2471
                add(ma[i]);
jaroslav@56
  2472
            }
jaroslav@56
  2473
        }
jaroslav@56
  2474
jaroslav@56
  2475
        void addAll(MethodArray ma) {
jaroslav@56
  2476
            for (int i = 0; i < ma.length(); i++) {
jaroslav@56
  2477
                add(ma.get(i));
jaroslav@56
  2478
            }
jaroslav@56
  2479
        }
jaroslav@56
  2480
jaroslav@56
  2481
        void addIfNotPresent(Method newMethod) {
jaroslav@56
  2482
            for (int i = 0; i < length; i++) {
jaroslav@56
  2483
                Method m = methods[i];
jaroslav@56
  2484
                if (m == newMethod || (m != null && m.equals(newMethod))) {
jaroslav@56
  2485
                    return;
jaroslav@56
  2486
                }
jaroslav@56
  2487
            }
jaroslav@56
  2488
            add(newMethod);
jaroslav@56
  2489
        }
jaroslav@56
  2490
jaroslav@56
  2491
        void addAllIfNotPresent(MethodArray newMethods) {
jaroslav@56
  2492
            for (int i = 0; i < newMethods.length(); i++) {
jaroslav@56
  2493
                Method m = newMethods.get(i);
jaroslav@56
  2494
                if (m != null) {
jaroslav@56
  2495
                    addIfNotPresent(m);
jaroslav@56
  2496
                }
jaroslav@56
  2497
            }
jaroslav@56
  2498
        }
jaroslav@56
  2499
jaroslav@56
  2500
        int length() {
jaroslav@56
  2501
            return length;
jaroslav@56
  2502
        }
jaroslav@56
  2503
jaroslav@56
  2504
        Method get(int i) {
jaroslav@56
  2505
            return methods[i];
jaroslav@56
  2506
        }
jaroslav@56
  2507
jaroslav@56
  2508
        void removeByNameAndSignature(Method toRemove) {
jaroslav@56
  2509
            for (int i = 0; i < length; i++) {
jaroslav@56
  2510
                Method m = methods[i];
jaroslav@56
  2511
                if (m != null &&
jaroslav@56
  2512
                    m.getReturnType() == toRemove.getReturnType() &&
jaroslav@56
  2513
                    m.getName() == toRemove.getName() &&
jaroslav@56
  2514
                    arrayContentsEq(m.getParameterTypes(),
jaroslav@56
  2515
                                    toRemove.getParameterTypes())) {
jaroslav@56
  2516
                    methods[i] = null;
jaroslav@56
  2517
                }
jaroslav@56
  2518
            }
jaroslav@56
  2519
        }
jaroslav@56
  2520
jaroslav@56
  2521
        void compactAndTrim() {
jaroslav@56
  2522
            int newPos = 0;
jaroslav@56
  2523
            // Get rid of null slots
jaroslav@56
  2524
            for (int pos = 0; pos < length; pos++) {
jaroslav@56
  2525
                Method m = methods[pos];
jaroslav@56
  2526
                if (m != null) {
jaroslav@56
  2527
                    if (pos != newPos) {
jaroslav@56
  2528
                        methods[newPos] = m;
jaroslav@56
  2529
                    }
jaroslav@56
  2530
                    newPos++;
jaroslav@56
  2531
                }
jaroslav@56
  2532
            }
jaroslav@56
  2533
            if (newPos != methods.length) {
jaroslav@56
  2534
                methods = Arrays.copyOf(methods, newPos);
jaroslav@56
  2535
            }
jaroslav@56
  2536
        }
jaroslav@56
  2537
jaroslav@56
  2538
        Method[] getArray() {
jaroslav@56
  2539
            return methods;
jaroslav@56
  2540
        }
jaroslav@56
  2541
    }
jaroslav@56
  2542
jaroslav@56
  2543
jaroslav@56
  2544
    // Returns an array of "root" methods. These Method objects must NOT
jaroslav@56
  2545
    // be propagated to the outside world, but must instead be copied
jaroslav@56
  2546
    // via ReflectionFactory.copyMethod.
jaroslav@56
  2547
    private Method[] privateGetPublicMethods() {
jaroslav@56
  2548
        checkInitted();
jaroslav@56
  2549
        Method[] res = null;
jaroslav@56
  2550
        if (useCaches) {
jaroslav@56
  2551
            clearCachesOnClassRedefinition();
jaroslav@56
  2552
            if (publicMethods != null) {
jaroslav@56
  2553
                res = publicMethods.get();
jaroslav@56
  2554
            }
jaroslav@56
  2555
            if (res != null) return res;
jaroslav@56
  2556
        }
jaroslav@56
  2557
jaroslav@56
  2558
        // No cached value available; compute value recursively.
jaroslav@56
  2559
        // Start by fetching public declared methods
jaroslav@56
  2560
        MethodArray methods = new MethodArray();
jaroslav@56
  2561
        {
jaroslav@56
  2562
            Method[] tmp = privateGetDeclaredMethods(true);
jaroslav@56
  2563
            methods.addAll(tmp);
jaroslav@56
  2564
        }
jaroslav@56
  2565
        // Now recur over superclass and direct superinterfaces.
jaroslav@56
  2566
        // Go over superinterfaces first so we can more easily filter
jaroslav@56
  2567
        // out concrete implementations inherited from superclasses at
jaroslav@56
  2568
        // the end.
jaroslav@56
  2569
        MethodArray inheritedMethods = new MethodArray();
jaroslav@56
  2570
        Class<?>[] interfaces = getInterfaces();
jaroslav@56
  2571
        for (int i = 0; i < interfaces.length; i++) {
jaroslav@56
  2572
            inheritedMethods.addAll(interfaces[i].privateGetPublicMethods());
jaroslav@56
  2573
        }
jaroslav@56
  2574
        if (!isInterface()) {
jaroslav@56
  2575
            Class<?> c = getSuperclass();
jaroslav@56
  2576
            if (c != null) {
jaroslav@56
  2577
                MethodArray supers = new MethodArray();
jaroslav@56
  2578
                supers.addAll(c.privateGetPublicMethods());
jaroslav@56
  2579
                // Filter out concrete implementations of any
jaroslav@56
  2580
                // interface methods
jaroslav@56
  2581
                for (int i = 0; i < supers.length(); i++) {
jaroslav@56
  2582
                    Method m = supers.get(i);
jaroslav@56
  2583
                    if (m != null && !Modifier.isAbstract(m.getModifiers())) {
jaroslav@56
  2584
                        inheritedMethods.removeByNameAndSignature(m);
jaroslav@56
  2585
                    }
jaroslav@56
  2586
                }
jaroslav@56
  2587
                // Insert superclass's inherited methods before
jaroslav@56
  2588
                // superinterfaces' to satisfy getMethod's search
jaroslav@56
  2589
                // order
jaroslav@56
  2590
                supers.addAll(inheritedMethods);
jaroslav@56
  2591
                inheritedMethods = supers;
jaroslav@56
  2592
            }
jaroslav@56
  2593
        }
jaroslav@56
  2594
        // Filter out all local methods from inherited ones
jaroslav@56
  2595
        for (int i = 0; i < methods.length(); i++) {
jaroslav@56
  2596
            Method m = methods.get(i);
jaroslav@56
  2597
            inheritedMethods.removeByNameAndSignature(m);
jaroslav@56
  2598
        }
jaroslav@56
  2599
        methods.addAllIfNotPresent(inheritedMethods);
jaroslav@56
  2600
        methods.compactAndTrim();
jaroslav@56
  2601
        res = methods.getArray();
jaroslav@56
  2602
        if (useCaches) {
jaroslav@56
  2603
            publicMethods = new SoftReference<>(res);
jaroslav@56
  2604
        }
jaroslav@56
  2605
        return res;
jaroslav@56
  2606
    }
jaroslav@56
  2607
jaroslav@56
  2608
jaroslav@56
  2609
    //
jaroslav@56
  2610
    // Helpers for fetchers of one field, method, or constructor
jaroslav@56
  2611
    //
jaroslav@56
  2612
jaroslav@56
  2613
    private Field searchFields(Field[] fields, String name) {
jaroslav@56
  2614
        String internedName = name.intern();
jaroslav@56
  2615
        for (int i = 0; i < fields.length; i++) {
jaroslav@56
  2616
            if (fields[i].getName() == internedName) {
jaroslav@56
  2617
                return getReflectionFactory().copyField(fields[i]);
jaroslav@56
  2618
            }
jaroslav@56
  2619
        }
jaroslav@56
  2620
        return null;
jaroslav@56
  2621
    }
jaroslav@56
  2622
jaroslav@56
  2623
    private Field getField0(String name) throws NoSuchFieldException {
jaroslav@56
  2624
        // Note: the intent is that the search algorithm this routine
jaroslav@56
  2625
        // uses be equivalent to the ordering imposed by
jaroslav@56
  2626
        // privateGetPublicFields(). It fetches only the declared
jaroslav@56
  2627
        // public fields for each class, however, to reduce the number
jaroslav@56
  2628
        // of Field objects which have to be created for the common
jaroslav@56
  2629
        // case where the field being requested is declared in the
jaroslav@56
  2630
        // class which is being queried.
jaroslav@56
  2631
        Field res = null;
jaroslav@56
  2632
        // Search declared public fields
jaroslav@56
  2633
        if ((res = searchFields(privateGetDeclaredFields(true), name)) != null) {
jaroslav@56
  2634
            return res;
jaroslav@56
  2635
        }
jaroslav@56
  2636
        // Direct superinterfaces, recursively
jaroslav@56
  2637
        Class<?>[] interfaces = getInterfaces();
jaroslav@56
  2638
        for (int i = 0; i < interfaces.length; i++) {
jaroslav@56
  2639
            Class<?> c = interfaces[i];
jaroslav@56
  2640
            if ((res = c.getField0(name)) != null) {
jaroslav@56
  2641
                return res;
jaroslav@56
  2642
            }
jaroslav@56
  2643
        }
jaroslav@56
  2644
        // Direct superclass, recursively
jaroslav@56
  2645
        if (!isInterface()) {
jaroslav@56
  2646
            Class<?> c = getSuperclass();
jaroslav@56
  2647
            if (c != null) {
jaroslav@56
  2648
                if ((res = c.getField0(name)) != null) {
jaroslav@56
  2649
                    return res;
jaroslav@56
  2650
                }
jaroslav@56
  2651
            }
jaroslav@56
  2652
        }
jaroslav@56
  2653
        return null;
jaroslav@56
  2654
    }
jaroslav@56
  2655
jaroslav@56
  2656
    private static Method searchMethods(Method[] methods,
jaroslav@56
  2657
                                        String name,
jaroslav@56
  2658
                                        Class<?>[] parameterTypes)
jaroslav@56
  2659
    {
jaroslav@56
  2660
        Method res = null;
jaroslav@56
  2661
        String internedName = name.intern();
jaroslav@56
  2662
        for (int i = 0; i < methods.length; i++) {
jaroslav@56
  2663
            Method m = methods[i];
jaroslav@56
  2664
            if (m.getName() == internedName
jaroslav@56
  2665
                && arrayContentsEq(parameterTypes, m.getParameterTypes())
jaroslav@56
  2666
                && (res == null
jaroslav@56
  2667
                    || res.getReturnType().isAssignableFrom(m.getReturnType())))
jaroslav@56
  2668
                res = m;
jaroslav@56
  2669
        }
jaroslav@56
  2670
jaroslav@56
  2671
        return (res == null ? res : getReflectionFactory().copyMethod(res));
jaroslav@56
  2672
    }
jaroslav@56
  2673
jaroslav@56
  2674
jaroslav@56
  2675
    private Method getMethod0(String name, Class<?>[] parameterTypes) {
jaroslav@56
  2676
        // Note: the intent is that the search algorithm this routine
jaroslav@56
  2677
        // uses be equivalent to the ordering imposed by
jaroslav@56
  2678
        // privateGetPublicMethods(). It fetches only the declared
jaroslav@56
  2679
        // public methods for each class, however, to reduce the
jaroslav@56
  2680
        // number of Method objects which have to be created for the
jaroslav@56
  2681
        // common case where the method being requested is declared in
jaroslav@56
  2682
        // the class which is being queried.
jaroslav@56
  2683
        Method res = null;
jaroslav@56
  2684
        // Search declared public methods
jaroslav@56
  2685
        if ((res = searchMethods(privateGetDeclaredMethods(true),
jaroslav@56
  2686
                                 name,
jaroslav@56
  2687
                                 parameterTypes)) != null) {
jaroslav@56
  2688
            return res;
jaroslav@56
  2689
        }
jaroslav@56
  2690
        // Search superclass's methods
jaroslav@56
  2691
        if (!isInterface()) {
jaroslav@56
  2692
            Class<? super T> c = getSuperclass();
jaroslav@56
  2693
            if (c != null) {
jaroslav@56
  2694
                if ((res = c.getMethod0(name, parameterTypes)) != null) {
jaroslav@56
  2695
                    return res;
jaroslav@56
  2696
                }
jaroslav@56
  2697
            }
jaroslav@56
  2698
        }
jaroslav@56
  2699
        // Search superinterfaces' methods
jaroslav@56
  2700
        Class<?>[] interfaces = getInterfaces();
jaroslav@56
  2701
        for (int i = 0; i < interfaces.length; i++) {
jaroslav@56
  2702
            Class<?> c = interfaces[i];
jaroslav@56
  2703
            if ((res = c.getMethod0(name, parameterTypes)) != null) {
jaroslav@56
  2704
                return res;
jaroslav@56
  2705
            }
jaroslav@56
  2706
        }
jaroslav@56
  2707
        // Not found
jaroslav@56
  2708
        return null;
jaroslav@56
  2709
    }
jaroslav@56
  2710
jaroslav@56
  2711
    private Constructor<T> getConstructor0(Class<?>[] parameterTypes,
jaroslav@56
  2712
                                        int which) throws NoSuchMethodException
jaroslav@56
  2713
    {
jaroslav@56
  2714
        Constructor<T>[] constructors = privateGetDeclaredConstructors((which == Member.PUBLIC));
jaroslav@56
  2715
        for (Constructor<T> constructor : constructors) {
jaroslav@56
  2716
            if (arrayContentsEq(parameterTypes,
jaroslav@56
  2717
                                constructor.getParameterTypes())) {
jaroslav@56
  2718
                return getReflectionFactory().copyConstructor(constructor);
jaroslav@56
  2719
            }
jaroslav@56
  2720
        }
jaroslav@56
  2721
        throw new NoSuchMethodException(getName() + ".<init>" + argumentTypesToString(parameterTypes));
jaroslav@56
  2722
    }
jaroslav@56
  2723
jaroslav@56
  2724
    //
jaroslav@56
  2725
    // Other helpers and base implementation
jaroslav@56
  2726
    //
jaroslav@56
  2727
jaroslav@56
  2728
    private static boolean arrayContentsEq(Object[] a1, Object[] a2) {
jaroslav@56
  2729
        if (a1 == null) {
jaroslav@56
  2730
            return a2 == null || a2.length == 0;
jaroslav@56
  2731
        }
jaroslav@56
  2732
jaroslav@56
  2733
        if (a2 == null) {
jaroslav@56
  2734
            return a1.length == 0;
jaroslav@56
  2735
        }
jaroslav@56
  2736
jaroslav@56
  2737
        if (a1.length != a2.length) {
jaroslav@56
  2738
            return false;
jaroslav@56
  2739
        }
jaroslav@56
  2740
jaroslav@56
  2741
        for (int i = 0; i < a1.length; i++) {
jaroslav@56
  2742
            if (a1[i] != a2[i]) {
jaroslav@56
  2743
                return false;
jaroslav@56
  2744
            }
jaroslav@56
  2745
        }
jaroslav@56
  2746
jaroslav@56
  2747
        return true;
jaroslav@56
  2748
    }
jaroslav@56
  2749
jaroslav@56
  2750
    private static Field[] copyFields(Field[] arg) {
jaroslav@56
  2751
        Field[] out = new Field[arg.length];
jaroslav@56
  2752
        ReflectionFactory fact = getReflectionFactory();
jaroslav@56
  2753
        for (int i = 0; i < arg.length; i++) {
jaroslav@56
  2754
            out[i] = fact.copyField(arg[i]);
jaroslav@56
  2755
        }
jaroslav@56
  2756
        return out;
jaroslav@56
  2757
    }
jaroslav@56
  2758
jaroslav@56
  2759
    private static Method[] copyMethods(Method[] arg) {
jaroslav@56
  2760
        Method[] out = new Method[arg.length];
jaroslav@56
  2761
        ReflectionFactory fact = getReflectionFactory();
jaroslav@56
  2762
        for (int i = 0; i < arg.length; i++) {
jaroslav@56
  2763
            out[i] = fact.copyMethod(arg[i]);
jaroslav@56
  2764
        }
jaroslav@56
  2765
        return out;
jaroslav@56
  2766
    }
jaroslav@56
  2767
jaroslav@56
  2768
    private static <U> Constructor<U>[] copyConstructors(Constructor<U>[] arg) {
jaroslav@56
  2769
        Constructor<U>[] out = arg.clone();
jaroslav@56
  2770
        ReflectionFactory fact = getReflectionFactory();
jaroslav@56
  2771
        for (int i = 0; i < out.length; i++) {
jaroslav@56
  2772
            out[i] = fact.copyConstructor(out[i]);
jaroslav@56
  2773
        }
jaroslav@56
  2774
        return out;
jaroslav@56
  2775
    }
jaroslav@56
  2776
jaroslav@56
  2777
    private native Field[]       getDeclaredFields0(boolean publicOnly);
jaroslav@56
  2778
    private native Method[]      getDeclaredMethods0(boolean publicOnly);
jaroslav@56
  2779
    private native Constructor<T>[] getDeclaredConstructors0(boolean publicOnly);
jaroslav@56
  2780
    private native Class<?>[]   getDeclaredClasses0();
jaroslav@56
  2781
jaroslav@56
  2782
    private static String        argumentTypesToString(Class<?>[] argTypes) {
jaroslav@56
  2783
        StringBuilder buf = new StringBuilder();
jaroslav@56
  2784
        buf.append("(");
jaroslav@56
  2785
        if (argTypes != null) {
jaroslav@56
  2786
            for (int i = 0; i < argTypes.length; i++) {
jaroslav@56
  2787
                if (i > 0) {
jaroslav@56
  2788
                    buf.append(", ");
jaroslav@56
  2789
                }
jaroslav@56
  2790
                Class<?> c = argTypes[i];
jaroslav@56
  2791
                buf.append((c == null) ? "null" : c.getName());
jaroslav@56
  2792
            }
jaroslav@56
  2793
        }
jaroslav@56
  2794
        buf.append(")");
jaroslav@56
  2795
        return buf.toString();
jaroslav@56
  2796
    }
jaroslav@56
  2797
jaroslav@56
  2798
    /** use serialVersionUID from JDK 1.1 for interoperability */
jaroslav@56
  2799
    private static final long serialVersionUID = 3206093459760846163L;
jaroslav@56
  2800
jaroslav@56
  2801
jaroslav@56
  2802
    /**
jaroslav@56
  2803
     * Class Class is special cased within the Serialization Stream Protocol.
jaroslav@56
  2804
     *
jaroslav@56
  2805
     * A Class instance is written initially into an ObjectOutputStream in the
jaroslav@56
  2806
     * following format:
jaroslav@56
  2807
     * <pre>
jaroslav@56
  2808
     *      {@code TC_CLASS} ClassDescriptor
jaroslav@56
  2809
     *      A ClassDescriptor is a special cased serialization of
jaroslav@56
  2810
     *      a {@code java.io.ObjectStreamClass} instance.
jaroslav@56
  2811
     * </pre>
jaroslav@56
  2812
     * A new handle is generated for the initial time the class descriptor
jaroslav@56
  2813
     * is written into the stream. Future references to the class descriptor
jaroslav@56
  2814
     * are written as references to the initial class descriptor instance.
jaroslav@56
  2815
     *
jaroslav@56
  2816
     * @see java.io.ObjectStreamClass
jaroslav@56
  2817
     */
jaroslav@56
  2818
    private static final ObjectStreamField[] serialPersistentFields =
jaroslav@56
  2819
        new ObjectStreamField[0];
jaroslav@56
  2820
jaroslav@56
  2821
jaroslav@56
  2822
    /**
jaroslav@56
  2823
     * Returns the assertion status that would be assigned to this
jaroslav@56
  2824
     * class if it were to be initialized at the time this method is invoked.
jaroslav@56
  2825
     * If this class has had its assertion status set, the most recent
jaroslav@56
  2826
     * setting will be returned; otherwise, if any package default assertion
jaroslav@56
  2827
     * status pertains to this class, the most recent setting for the most
jaroslav@56
  2828
     * specific pertinent package default assertion status is returned;
jaroslav@56
  2829
     * otherwise, if this class is not a system class (i.e., it has a
jaroslav@56
  2830
     * class loader) its class loader's default assertion status is returned;
jaroslav@56
  2831
     * otherwise, the system class default assertion status is returned.
jaroslav@56
  2832
     * <p>
jaroslav@56
  2833
     * Few programmers will have any need for this method; it is provided
jaroslav@56
  2834
     * for the benefit of the JRE itself.  (It allows a class to determine at
jaroslav@56
  2835
     * the time that it is initialized whether assertions should be enabled.)
jaroslav@56
  2836
     * Note that this method is not guaranteed to return the actual
jaroslav@56
  2837
     * assertion status that was (or will be) associated with the specified
jaroslav@56
  2838
     * class when it was (or will be) initialized.
jaroslav@56
  2839
     *
jaroslav@56
  2840
     * @return the desired assertion status of the specified class.
jaroslav@56
  2841
     * @see    java.lang.ClassLoader#setClassAssertionStatus
jaroslav@56
  2842
     * @see    java.lang.ClassLoader#setPackageAssertionStatus
jaroslav@56
  2843
     * @see    java.lang.ClassLoader#setDefaultAssertionStatus
jaroslav@56
  2844
     * @since  1.4
jaroslav@56
  2845
     */
jaroslav@56
  2846
    public boolean desiredAssertionStatus() {
jaroslav@56
  2847
        ClassLoader loader = getClassLoader();
jaroslav@56
  2848
        // If the loader is null this is a system class, so ask the VM
jaroslav@56
  2849
        if (loader == null)
jaroslav@56
  2850
            return desiredAssertionStatus0(this);
jaroslav@56
  2851
jaroslav@56
  2852
        // If the classloader has been initialized with the assertion
jaroslav@56
  2853
        // directives, ask it. Otherwise, ask the VM.
jaroslav@56
  2854
        synchronized(loader.assertionLock) {
jaroslav@56
  2855
            if (loader.classAssertionStatus != null) {
jaroslav@56
  2856
                return loader.desiredAssertionStatus(getName());
jaroslav@56
  2857
            }
jaroslav@56
  2858
        }
jaroslav@56
  2859
        return desiredAssertionStatus0(this);
jaroslav@56
  2860
    }
jaroslav@56
  2861
jaroslav@56
  2862
    // Retrieves the desired assertion status of this class from the VM
jaroslav@56
  2863
    private static native boolean desiredAssertionStatus0(Class<?> clazz);
jaroslav@56
  2864
jaroslav@56
  2865
    /**
jaroslav@56
  2866
     * Returns true if and only if this class was declared as an enum in the
jaroslav@56
  2867
     * source code.
jaroslav@56
  2868
     *
jaroslav@56
  2869
     * @return true if and only if this class was declared as an enum in the
jaroslav@56
  2870
     *     source code
jaroslav@56
  2871
     * @since 1.5
jaroslav@56
  2872
     */
jaroslav@56
  2873
    public boolean isEnum() {
jaroslav@56
  2874
        // An enum must both directly extend java.lang.Enum and have
jaroslav@56
  2875
        // the ENUM bit set; classes for specialized enum constants
jaroslav@56
  2876
        // don't do the former.
jaroslav@56
  2877
        return (this.getModifiers() & ENUM) != 0 &&
jaroslav@56
  2878
        this.getSuperclass() == java.lang.Enum.class;
jaroslav@56
  2879
    }
jaroslav@56
  2880
jaroslav@56
  2881
    // Fetches the factory for reflective objects
jaroslav@56
  2882
    private static ReflectionFactory getReflectionFactory() {
jaroslav@56
  2883
        if (reflectionFactory == null) {
jaroslav@56
  2884
            reflectionFactory =
jaroslav@56
  2885
                java.security.AccessController.doPrivileged
jaroslav@56
  2886
                    (new sun.reflect.ReflectionFactory.GetReflectionFactoryAction());
jaroslav@56
  2887
        }
jaroslav@56
  2888
        return reflectionFactory;
jaroslav@56
  2889
    }
jaroslav@56
  2890
    private static ReflectionFactory reflectionFactory;
jaroslav@56
  2891
jaroslav@56
  2892
    // To be able to query system properties as soon as they're available
jaroslav@56
  2893
    private static boolean initted = false;
jaroslav@56
  2894
    private static void checkInitted() {
jaroslav@56
  2895
        if (initted) return;
jaroslav@56
  2896
        AccessController.doPrivileged(new PrivilegedAction<Void>() {
jaroslav@56
  2897
                public Void run() {
jaroslav@56
  2898
                    // Tests to ensure the system properties table is fully
jaroslav@56
  2899
                    // initialized. This is needed because reflection code is
jaroslav@56
  2900
                    // called very early in the initialization process (before
jaroslav@56
  2901
                    // command-line arguments have been parsed and therefore
jaroslav@56
  2902
                    // these user-settable properties installed.) We assume that
jaroslav@56
  2903
                    // if System.out is non-null then the System class has been
jaroslav@56
  2904
                    // fully initialized and that the bulk of the startup code
jaroslav@56
  2905
                    // has been run.
jaroslav@56
  2906
jaroslav@56
  2907
                    if (System.out == null) {
jaroslav@56
  2908
                        // java.lang.System not yet fully initialized
jaroslav@56
  2909
                        return null;
jaroslav@56
  2910
                    }
jaroslav@56
  2911
jaroslav@56
  2912
                    String val =
jaroslav@56
  2913
                        System.getProperty("sun.reflect.noCaches");
jaroslav@56
  2914
                    if (val != null && val.equals("true")) {
jaroslav@56
  2915
                        useCaches = false;
jaroslav@56
  2916
                    }
jaroslav@56
  2917
jaroslav@56
  2918
                    initted = true;
jaroslav@56
  2919
                    return null;
jaroslav@56
  2920
                }
jaroslav@56
  2921
            });
jaroslav@56
  2922
    }
jaroslav@56
  2923
jaroslav@56
  2924
    /**
jaroslav@56
  2925
     * Returns the elements of this enum class or null if this
jaroslav@56
  2926
     * Class object does not represent an enum type.
jaroslav@56
  2927
     *
jaroslav@56
  2928
     * @return an array containing the values comprising the enum class
jaroslav@56
  2929
     *     represented by this Class object in the order they're
jaroslav@56
  2930
     *     declared, or null if this Class object does not
jaroslav@56
  2931
     *     represent an enum type
jaroslav@56
  2932
     * @since 1.5
jaroslav@56
  2933
     */
jaroslav@56
  2934
    public T[] getEnumConstants() {
jaroslav@56
  2935
        T[] values = getEnumConstantsShared();
jaroslav@56
  2936
        return (values != null) ? values.clone() : null;
jaroslav@56
  2937
    }
jaroslav@56
  2938
jaroslav@56
  2939
    /**
jaroslav@56
  2940
     * Returns the elements of this enum class or null if this
jaroslav@56
  2941
     * Class object does not represent an enum type;
jaroslav@56
  2942
     * identical to getEnumConstants except that the result is
jaroslav@56
  2943
     * uncloned, cached, and shared by all callers.
jaroslav@56
  2944
     */
jaroslav@56
  2945
    T[] getEnumConstantsShared() {
jaroslav@56
  2946
        if (enumConstants == null) {
jaroslav@56
  2947
            if (!isEnum()) return null;
jaroslav@56
  2948
            try {
jaroslav@56
  2949
                final Method values = getMethod("values");
jaroslav@56
  2950
                java.security.AccessController.doPrivileged(
jaroslav@56
  2951
                    new java.security.PrivilegedAction<Void>() {
jaroslav@56
  2952
                        public Void run() {
jaroslav@56
  2953
                                values.setAccessible(true);
jaroslav@56
  2954
                                return null;
jaroslav@56
  2955
                            }
jaroslav@56
  2956
                        });
jaroslav@56
  2957
                enumConstants = (T[])values.invoke(null);
jaroslav@56
  2958
            }
jaroslav@56
  2959
            // These can happen when users concoct enum-like classes
jaroslav@56
  2960
            // that don't comply with the enum spec.
jaroslav@56
  2961
            catch (InvocationTargetException ex) { return null; }
jaroslav@56
  2962
            catch (NoSuchMethodException ex) { return null; }
jaroslav@56
  2963
            catch (IllegalAccessException ex) { return null; }
jaroslav@56
  2964
        }
jaroslav@56
  2965
        return enumConstants;
jaroslav@56
  2966
    }
jaroslav@56
  2967
    private volatile transient T[] enumConstants = null;
jaroslav@56
  2968
jaroslav@56
  2969
    /**
jaroslav@56
  2970
     * Returns a map from simple name to enum constant.  This package-private
jaroslav@56
  2971
     * method is used internally by Enum to implement
jaroslav@56
  2972
     *     public static <T extends Enum<T>> T valueOf(Class<T>, String)
jaroslav@56
  2973
     * efficiently.  Note that the map is returned by this method is
jaroslav@56
  2974
     * created lazily on first use.  Typically it won't ever get created.
jaroslav@56
  2975
     */
jaroslav@56
  2976
    Map<String, T> enumConstantDirectory() {
jaroslav@56
  2977
        if (enumConstantDirectory == null) {
jaroslav@56
  2978
            T[] universe = getEnumConstantsShared();
jaroslav@56
  2979
            if (universe == null)
jaroslav@56
  2980
                throw new IllegalArgumentException(
jaroslav@56
  2981
                    getName() + " is not an enum type");
jaroslav@56
  2982
            Map<String, T> m = new HashMap<>(2 * universe.length);
jaroslav@56
  2983
            for (T constant : universe)
jaroslav@56
  2984
                m.put(((Enum<?>)constant).name(), constant);
jaroslav@56
  2985
            enumConstantDirectory = m;
jaroslav@56
  2986
        }
jaroslav@56
  2987
        return enumConstantDirectory;
jaroslav@56
  2988
    }
jaroslav@56
  2989
    private volatile transient Map<String, T> enumConstantDirectory = null;
jaroslav@56
  2990
jaroslav@56
  2991
    /**
jaroslav@56
  2992
     * Casts an object to the class or interface represented
jaroslav@56
  2993
     * by this {@code Class} object.
jaroslav@56
  2994
     *
jaroslav@56
  2995
     * @param obj the object to be cast
jaroslav@56
  2996
     * @return the object after casting, or null if obj is null
jaroslav@56
  2997
     *
jaroslav@56
  2998
     * @throws ClassCastException if the object is not
jaroslav@56
  2999
     * null and is not assignable to the type T.
jaroslav@56
  3000
     *
jaroslav@56
  3001
     * @since 1.5
jaroslav@56
  3002
     */
jaroslav@56
  3003
    public T cast(Object obj) {
jaroslav@56
  3004
        if (obj != null && !isInstance(obj))
jaroslav@56
  3005
            throw new ClassCastException(cannotCastMsg(obj));
jaroslav@56
  3006
        return (T) obj;
jaroslav@56
  3007
    }
jaroslav@56
  3008
jaroslav@56
  3009
    private String cannotCastMsg(Object obj) {
jaroslav@56
  3010
        return "Cannot cast " + obj.getClass().getName() + " to " + getName();
jaroslav@56
  3011
    }
jaroslav@56
  3012
jaroslav@56
  3013
    /**
jaroslav@56
  3014
     * Casts this {@code Class} object to represent a subclass of the class
jaroslav@56
  3015
     * represented by the specified class object.  Checks that that the cast
jaroslav@56
  3016
     * is valid, and throws a {@code ClassCastException} if it is not.  If
jaroslav@56
  3017
     * this method succeeds, it always returns a reference to this class object.
jaroslav@56
  3018
     *
jaroslav@56
  3019
     * <p>This method is useful when a client needs to "narrow" the type of
jaroslav@56
  3020
     * a {@code Class} object to pass it to an API that restricts the
jaroslav@56
  3021
     * {@code Class} objects that it is willing to accept.  A cast would
jaroslav@56
  3022
     * generate a compile-time warning, as the correctness of the cast
jaroslav@56
  3023
     * could not be checked at runtime (because generic types are implemented
jaroslav@56
  3024
     * by erasure).
jaroslav@56
  3025
     *
jaroslav@56
  3026
     * @return this {@code Class} object, cast to represent a subclass of
jaroslav@56
  3027
     *    the specified class object.
jaroslav@56
  3028
     * @throws ClassCastException if this {@code Class} object does not
jaroslav@56
  3029
     *    represent a subclass of the specified class (here "subclass" includes
jaroslav@56
  3030
     *    the class itself).
jaroslav@56
  3031
     * @since 1.5
jaroslav@56
  3032
     */
jaroslav@56
  3033
    public <U> Class<? extends U> asSubclass(Class<U> clazz) {
jaroslav@56
  3034
        if (clazz.isAssignableFrom(this))
jaroslav@56
  3035
            return (Class<? extends U>) this;
jaroslav@56
  3036
        else
jaroslav@56
  3037
            throw new ClassCastException(this.toString());
jaroslav@56
  3038
    }
jaroslav@56
  3039
jaroslav@56
  3040
    /**
jaroslav@56
  3041
     * @throws NullPointerException {@inheritDoc}
jaroslav@56
  3042
     * @since 1.5
jaroslav@56
  3043
     */
jaroslav@56
  3044
    public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {
jaroslav@56
  3045
        if (annotationClass == null)
jaroslav@56
  3046
            throw new NullPointerException();
jaroslav@56
  3047
jaroslav@56
  3048
        initAnnotationsIfNecessary();
jaroslav@56
  3049
        return (A) annotations.get(annotationClass);
jaroslav@56
  3050
    }
jaroslav@56
  3051
jaroslav@56
  3052
    /**
jaroslav@56
  3053
     * @throws NullPointerException {@inheritDoc}
jaroslav@56
  3054
     * @since 1.5
jaroslav@56
  3055
     */
jaroslav@56
  3056
    public boolean isAnnotationPresent(
jaroslav@56
  3057
        Class<? extends Annotation> annotationClass) {
jaroslav@56
  3058
        if (annotationClass == null)
jaroslav@56
  3059
            throw new NullPointerException();
jaroslav@56
  3060
jaroslav@56
  3061
        return getAnnotation(annotationClass) != null;
jaroslav@56
  3062
    }
jaroslav@56
  3063
jaroslav@56
  3064
jaroslav@56
  3065
    /**
jaroslav@56
  3066
     * @since 1.5
jaroslav@56
  3067
     */
jaroslav@56
  3068
    public Annotation[] getAnnotations() {
jaroslav@56
  3069
        initAnnotationsIfNecessary();
jaroslav@56
  3070
        return AnnotationParser.toArray(annotations);
jaroslav@56
  3071
    }
jaroslav@56
  3072
jaroslav@56
  3073
    /**
jaroslav@56
  3074
     * @since 1.5
jaroslav@56
  3075
     */
jaroslav@56
  3076
    public Annotation[] getDeclaredAnnotations()  {
jaroslav@56
  3077
        initAnnotationsIfNecessary();
jaroslav@56
  3078
        return AnnotationParser.toArray(declaredAnnotations);
jaroslav@56
  3079
    }
jaroslav@56
  3080
jaroslav@56
  3081
    // Annotations cache
jaroslav@56
  3082
    private transient Map<Class<? extends Annotation>, Annotation> annotations;
jaroslav@56
  3083
    private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
jaroslav@56
  3084
jaroslav@56
  3085
    private synchronized void initAnnotationsIfNecessary() {
jaroslav@56
  3086
        clearCachesOnClassRedefinition();
jaroslav@56
  3087
        if (annotations != null)
jaroslav@56
  3088
            return;
jaroslav@56
  3089
        declaredAnnotations = AnnotationParser.parseAnnotations(
jaroslav@56
  3090
            getRawAnnotations(), getConstantPool(), this);
jaroslav@56
  3091
        Class<?> superClass = getSuperclass();
jaroslav@56
  3092
        if (superClass == null) {
jaroslav@56
  3093
            annotations = declaredAnnotations;
jaroslav@56
  3094
        } else {
jaroslav@56
  3095
            annotations = new HashMap<>();
jaroslav@56
  3096
            superClass.initAnnotationsIfNecessary();
jaroslav@56
  3097
            for (Map.Entry<Class<? extends Annotation>, Annotation> e : superClass.annotations.entrySet()) {
jaroslav@56
  3098
                Class<? extends Annotation> annotationClass = e.getKey();
jaroslav@56
  3099
                if (AnnotationType.getInstance(annotationClass).isInherited())
jaroslav@56
  3100
                    annotations.put(annotationClass, e.getValue());
jaroslav@56
  3101
            }
jaroslav@56
  3102
            annotations.putAll(declaredAnnotations);
jaroslav@56
  3103
        }
jaroslav@56
  3104
    }
jaroslav@56
  3105
jaroslav@56
  3106
    // Annotation types cache their internal (AnnotationType) form
jaroslav@56
  3107
jaroslav@56
  3108
    private AnnotationType annotationType;
jaroslav@56
  3109
jaroslav@56
  3110
    void setAnnotationType(AnnotationType type) {
jaroslav@56
  3111
        annotationType = type;
jaroslav@56
  3112
    }
jaroslav@56
  3113
jaroslav@56
  3114
    AnnotationType getAnnotationType() {
jaroslav@56
  3115
        return annotationType;
jaroslav@56
  3116
    }
jaroslav@56
  3117
}