1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/emul/src/main/java/java/lang/Class.java Sat Sep 29 06:47:05 2012 +0200
1.3 @@ -0,0 +1,3117 @@
1.4 +/*
1.5 + * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
1.7 + *
1.8 + * This code is free software; you can redistribute it and/or modify it
1.9 + * under the terms of the GNU General Public License version 2 only, as
1.10 + * published by the Free Software Foundation. Oracle designates this
1.11 + * particular file as subject to the "Classpath" exception as provided
1.12 + * by Oracle in the LICENSE file that accompanied this code.
1.13 + *
1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1.17 + * version 2 for more details (a copy is included in the LICENSE file that
1.18 + * accompanied this code).
1.19 + *
1.20 + * You should have received a copy of the GNU General Public License version
1.21 + * 2 along with this work; if not, write to the Free Software Foundation,
1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1.23 + *
1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1.25 + * or visit www.oracle.com if you need additional information or have any
1.26 + * questions.
1.27 + */
1.28 +
1.29 +package java.lang;
1.30 +
1.31 +import java.lang.reflect.Array;
1.32 +import java.lang.reflect.GenericArrayType;
1.33 +import java.lang.reflect.Member;
1.34 +import java.lang.reflect.Field;
1.35 +import java.lang.reflect.Method;
1.36 +import java.lang.reflect.Constructor;
1.37 +import java.lang.reflect.GenericDeclaration;
1.38 +import java.lang.reflect.Modifier;
1.39 +import java.lang.reflect.Type;
1.40 +import java.lang.reflect.TypeVariable;
1.41 +import java.lang.reflect.InvocationTargetException;
1.42 +import java.lang.ref.SoftReference;
1.43 +import java.io.InputStream;
1.44 +import java.io.ObjectStreamField;
1.45 +import java.security.AccessController;
1.46 +import java.security.PrivilegedAction;
1.47 +import java.util.ArrayList;
1.48 +import java.util.Arrays;
1.49 +import java.util.Collection;
1.50 +import java.util.HashSet;
1.51 +import java.util.Iterator;
1.52 +import java.util.List;
1.53 +import java.util.LinkedList;
1.54 +import java.util.LinkedHashSet;
1.55 +import java.util.Set;
1.56 +import java.util.Map;
1.57 +import java.util.HashMap;
1.58 +import sun.misc.Unsafe;
1.59 +import sun.reflect.ConstantPool;
1.60 +import sun.reflect.Reflection;
1.61 +import sun.reflect.ReflectionFactory;
1.62 +import sun.reflect.SignatureIterator;
1.63 +import sun.reflect.generics.factory.CoreReflectionFactory;
1.64 +import sun.reflect.generics.factory.GenericsFactory;
1.65 +import sun.reflect.generics.repository.ClassRepository;
1.66 +import sun.reflect.generics.repository.MethodRepository;
1.67 +import sun.reflect.generics.repository.ConstructorRepository;
1.68 +import sun.reflect.generics.scope.ClassScope;
1.69 +import sun.security.util.SecurityConstants;
1.70 +import java.lang.annotation.Annotation;
1.71 +import sun.reflect.annotation.*;
1.72 +
1.73 +/**
1.74 + * Instances of the class {@code Class} represent classes and
1.75 + * interfaces in a running Java application. An enum is a kind of
1.76 + * class and an annotation is a kind of interface. Every array also
1.77 + * belongs to a class that is reflected as a {@code Class} object
1.78 + * that is shared by all arrays with the same element type and number
1.79 + * of dimensions. The primitive Java types ({@code boolean},
1.80 + * {@code byte}, {@code char}, {@code short},
1.81 + * {@code int}, {@code long}, {@code float}, and
1.82 + * {@code double}), and the keyword {@code void} are also
1.83 + * represented as {@code Class} objects.
1.84 + *
1.85 + * <p> {@code Class} has no public constructor. Instead {@code Class}
1.86 + * objects are constructed automatically by the Java Virtual Machine as classes
1.87 + * are loaded and by calls to the {@code defineClass} method in the class
1.88 + * loader.
1.89 + *
1.90 + * <p> The following example uses a {@code Class} object to print the
1.91 + * class name of an object:
1.92 + *
1.93 + * <p> <blockquote><pre>
1.94 + * void printClassName(Object obj) {
1.95 + * System.out.println("The class of " + obj +
1.96 + * " is " + obj.getClass().getName());
1.97 + * }
1.98 + * </pre></blockquote>
1.99 + *
1.100 + * <p> It is also possible to get the {@code Class} object for a named
1.101 + * type (or for void) using a class literal. See Section 15.8.2 of
1.102 + * <cite>The Java™ Language Specification</cite>.
1.103 + * For example:
1.104 + *
1.105 + * <p> <blockquote>
1.106 + * {@code System.out.println("The name of class Foo is: "+Foo.class.getName());}
1.107 + * </blockquote>
1.108 + *
1.109 + * @param <T> the type of the class modeled by this {@code Class}
1.110 + * object. For example, the type of {@code String.class} is {@code
1.111 + * Class<String>}. Use {@code Class<?>} if the class being modeled is
1.112 + * unknown.
1.113 + *
1.114 + * @author unascribed
1.115 + * @see java.lang.ClassLoader#defineClass(byte[], int, int)
1.116 + * @since JDK1.0
1.117 + */
1.118 +public final
1.119 + class Class<T> implements java.io.Serializable,
1.120 + java.lang.reflect.GenericDeclaration,
1.121 + java.lang.reflect.Type,
1.122 + java.lang.reflect.AnnotatedElement {
1.123 + private static final int ANNOTATION= 0x00002000;
1.124 + private static final int ENUM = 0x00004000;
1.125 + private static final int SYNTHETIC = 0x00001000;
1.126 +
1.127 + private static native void registerNatives();
1.128 + static {
1.129 + registerNatives();
1.130 + }
1.131 +
1.132 + /*
1.133 + * Constructor. Only the Java Virtual Machine creates Class
1.134 + * objects.
1.135 + */
1.136 + private Class() {}
1.137 +
1.138 +
1.139 + /**
1.140 + * Converts the object to a string. The string representation is the
1.141 + * string "class" or "interface", followed by a space, and then by the
1.142 + * fully qualified name of the class in the format returned by
1.143 + * {@code getName}. If this {@code Class} object represents a
1.144 + * primitive type, this method returns the name of the primitive type. If
1.145 + * this {@code Class} object represents void this method returns
1.146 + * "void".
1.147 + *
1.148 + * @return a string representation of this class object.
1.149 + */
1.150 + public String toString() {
1.151 + return (isInterface() ? "interface " : (isPrimitive() ? "" : "class "))
1.152 + + getName();
1.153 + }
1.154 +
1.155 +
1.156 + /**
1.157 + * Returns the {@code Class} object associated with the class or
1.158 + * interface with the given string name. Invoking this method is
1.159 + * equivalent to:
1.160 + *
1.161 + * <blockquote>
1.162 + * {@code Class.forName(className, true, currentLoader)}
1.163 + * </blockquote>
1.164 + *
1.165 + * where {@code currentLoader} denotes the defining class loader of
1.166 + * the current class.
1.167 + *
1.168 + * <p> For example, the following code fragment returns the
1.169 + * runtime {@code Class} descriptor for the class named
1.170 + * {@code java.lang.Thread}:
1.171 + *
1.172 + * <blockquote>
1.173 + * {@code Class t = Class.forName("java.lang.Thread")}
1.174 + * </blockquote>
1.175 + * <p>
1.176 + * A call to {@code forName("X")} causes the class named
1.177 + * {@code X} to be initialized.
1.178 + *
1.179 + * @param className the fully qualified name of the desired class.
1.180 + * @return the {@code Class} object for the class with the
1.181 + * specified name.
1.182 + * @exception LinkageError if the linkage fails
1.183 + * @exception ExceptionInInitializerError if the initialization provoked
1.184 + * by this method fails
1.185 + * @exception ClassNotFoundException if the class cannot be located
1.186 + */
1.187 + public static Class<?> forName(String className)
1.188 + throws ClassNotFoundException {
1.189 + return forName0(className, true, ClassLoader.getCallerClassLoader());
1.190 + }
1.191 +
1.192 +
1.193 + /**
1.194 + * Returns the {@code Class} object associated with the class or
1.195 + * interface with the given string name, using the given class loader.
1.196 + * Given the fully qualified name for a class or interface (in the same
1.197 + * format returned by {@code getName}) this method attempts to
1.198 + * locate, load, and link the class or interface. The specified class
1.199 + * loader is used to load the class or interface. If the parameter
1.200 + * {@code loader} is null, the class is loaded through the bootstrap
1.201 + * class loader. The class is initialized only if the
1.202 + * {@code initialize} parameter is {@code true} and if it has
1.203 + * not been initialized earlier.
1.204 + *
1.205 + * <p> If {@code name} denotes a primitive type or void, an attempt
1.206 + * will be made to locate a user-defined class in the unnamed package whose
1.207 + * name is {@code name}. Therefore, this method cannot be used to
1.208 + * obtain any of the {@code Class} objects representing primitive
1.209 + * types or void.
1.210 + *
1.211 + * <p> If {@code name} denotes an array class, the component type of
1.212 + * the array class is loaded but not initialized.
1.213 + *
1.214 + * <p> For example, in an instance method the expression:
1.215 + *
1.216 + * <blockquote>
1.217 + * {@code Class.forName("Foo")}
1.218 + * </blockquote>
1.219 + *
1.220 + * is equivalent to:
1.221 + *
1.222 + * <blockquote>
1.223 + * {@code Class.forName("Foo", true, this.getClass().getClassLoader())}
1.224 + * </blockquote>
1.225 + *
1.226 + * Note that this method throws errors related to loading, linking or
1.227 + * initializing as specified in Sections 12.2, 12.3 and 12.4 of <em>The
1.228 + * Java Language Specification</em>.
1.229 + * Note that this method does not check whether the requested class
1.230 + * is accessible to its caller.
1.231 + *
1.232 + * <p> If the {@code loader} is {@code null}, and a security
1.233 + * manager is present, and the caller's class loader is not null, then this
1.234 + * method calls the security manager's {@code checkPermission} method
1.235 + * with a {@code RuntimePermission("getClassLoader")} permission to
1.236 + * ensure it's ok to access the bootstrap class loader.
1.237 + *
1.238 + * @param name fully qualified name of the desired class
1.239 + * @param initialize whether the class must be initialized
1.240 + * @param loader class loader from which the class must be loaded
1.241 + * @return class object representing the desired class
1.242 + *
1.243 + * @exception LinkageError if the linkage fails
1.244 + * @exception ExceptionInInitializerError if the initialization provoked
1.245 + * by this method fails
1.246 + * @exception ClassNotFoundException if the class cannot be located by
1.247 + * the specified class loader
1.248 + *
1.249 + * @see java.lang.Class#forName(String)
1.250 + * @see java.lang.ClassLoader
1.251 + * @since 1.2
1.252 + */
1.253 + public static Class<?> forName(String name, boolean initialize,
1.254 + ClassLoader loader)
1.255 + throws ClassNotFoundException
1.256 + {
1.257 + if (loader == null) {
1.258 + SecurityManager sm = System.getSecurityManager();
1.259 + if (sm != null) {
1.260 + ClassLoader ccl = ClassLoader.getCallerClassLoader();
1.261 + if (ccl != null) {
1.262 + sm.checkPermission(
1.263 + SecurityConstants.GET_CLASSLOADER_PERMISSION);
1.264 + }
1.265 + }
1.266 + }
1.267 + return forName0(name, initialize, loader);
1.268 + }
1.269 +
1.270 + /** Called after security checks have been made. */
1.271 + private static native Class<?> forName0(String name, boolean initialize,
1.272 + ClassLoader loader)
1.273 + throws ClassNotFoundException;
1.274 +
1.275 + /**
1.276 + * Creates a new instance of the class represented by this {@code Class}
1.277 + * object. The class is instantiated as if by a {@code new}
1.278 + * expression with an empty argument list. The class is initialized if it
1.279 + * has not already been initialized.
1.280 + *
1.281 + * <p>Note that this method propagates any exception thrown by the
1.282 + * nullary constructor, including a checked exception. Use of
1.283 + * this method effectively bypasses the compile-time exception
1.284 + * checking that would otherwise be performed by the compiler.
1.285 + * The {@link
1.286 + * java.lang.reflect.Constructor#newInstance(java.lang.Object...)
1.287 + * Constructor.newInstance} method avoids this problem by wrapping
1.288 + * any exception thrown by the constructor in a (checked) {@link
1.289 + * java.lang.reflect.InvocationTargetException}.
1.290 + *
1.291 + * @return a newly allocated instance of the class represented by this
1.292 + * object.
1.293 + * @exception IllegalAccessException if the class or its nullary
1.294 + * constructor is not accessible.
1.295 + * @exception InstantiationException
1.296 + * if this {@code Class} represents an abstract class,
1.297 + * an interface, an array class, a primitive type, or void;
1.298 + * or if the class has no nullary constructor;
1.299 + * or if the instantiation fails for some other reason.
1.300 + * @exception ExceptionInInitializerError if the initialization
1.301 + * provoked by this method fails.
1.302 + * @exception SecurityException
1.303 + * If a security manager, <i>s</i>, is present and any of the
1.304 + * following conditions is met:
1.305 + *
1.306 + * <ul>
1.307 + *
1.308 + * <li> invocation of
1.309 + * {@link SecurityManager#checkMemberAccess
1.310 + * s.checkMemberAccess(this, Member.PUBLIC)} denies
1.311 + * creation of new instances of this class
1.312 + *
1.313 + * <li> the caller's class loader is not the same as or an
1.314 + * ancestor of the class loader for the current class and
1.315 + * invocation of {@link SecurityManager#checkPackageAccess
1.316 + * s.checkPackageAccess()} denies access to the package
1.317 + * of this class
1.318 + *
1.319 + * </ul>
1.320 + *
1.321 + */
1.322 + public T newInstance()
1.323 + throws InstantiationException, IllegalAccessException
1.324 + {
1.325 + if (System.getSecurityManager() != null) {
1.326 + checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
1.327 + }
1.328 + return newInstance0();
1.329 + }
1.330 +
1.331 + private T newInstance0()
1.332 + throws InstantiationException, IllegalAccessException
1.333 + {
1.334 + // NOTE: the following code may not be strictly correct under
1.335 + // the current Java memory model.
1.336 +
1.337 + // Constructor lookup
1.338 + if (cachedConstructor == null) {
1.339 + if (this == Class.class) {
1.340 + throw new IllegalAccessException(
1.341 + "Can not call newInstance() on the Class for java.lang.Class"
1.342 + );
1.343 + }
1.344 + try {
1.345 + Class<?>[] empty = {};
1.346 + final Constructor<T> c = getConstructor0(empty, Member.DECLARED);
1.347 + // Disable accessibility checks on the constructor
1.348 + // since we have to do the security check here anyway
1.349 + // (the stack depth is wrong for the Constructor's
1.350 + // security check to work)
1.351 + java.security.AccessController.doPrivileged(
1.352 + new java.security.PrivilegedAction<Void>() {
1.353 + public Void run() {
1.354 + c.setAccessible(true);
1.355 + return null;
1.356 + }
1.357 + });
1.358 + cachedConstructor = c;
1.359 + } catch (NoSuchMethodException e) {
1.360 + throw new InstantiationException(getName());
1.361 + }
1.362 + }
1.363 + Constructor<T> tmpConstructor = cachedConstructor;
1.364 + // Security check (same as in java.lang.reflect.Constructor)
1.365 + int modifiers = tmpConstructor.getModifiers();
1.366 + if (!Reflection.quickCheckMemberAccess(this, modifiers)) {
1.367 + Class<?> caller = Reflection.getCallerClass(3);
1.368 + if (newInstanceCallerCache != caller) {
1.369 + Reflection.ensureMemberAccess(caller, this, null, modifiers);
1.370 + newInstanceCallerCache = caller;
1.371 + }
1.372 + }
1.373 + // Run constructor
1.374 + try {
1.375 + return tmpConstructor.newInstance((Object[])null);
1.376 + } catch (InvocationTargetException e) {
1.377 + Unsafe.getUnsafe().throwException(e.getTargetException());
1.378 + // Not reached
1.379 + return null;
1.380 + }
1.381 + }
1.382 + private volatile transient Constructor<T> cachedConstructor;
1.383 + private volatile transient Class<?> newInstanceCallerCache;
1.384 +
1.385 +
1.386 + /**
1.387 + * Determines if the specified {@code Object} is assignment-compatible
1.388 + * with the object represented by this {@code Class}. This method is
1.389 + * the dynamic equivalent of the Java language {@code instanceof}
1.390 + * operator. The method returns {@code true} if the specified
1.391 + * {@code Object} argument is non-null and can be cast to the
1.392 + * reference type represented by this {@code Class} object without
1.393 + * raising a {@code ClassCastException.} It returns {@code false}
1.394 + * otherwise.
1.395 + *
1.396 + * <p> Specifically, if this {@code Class} object represents a
1.397 + * declared class, this method returns {@code true} if the specified
1.398 + * {@code Object} argument is an instance of the represented class (or
1.399 + * of any of its subclasses); it returns {@code false} otherwise. If
1.400 + * this {@code Class} object represents an array class, this method
1.401 + * returns {@code true} if the specified {@code Object} argument
1.402 + * can be converted to an object of the array class by an identity
1.403 + * conversion or by a widening reference conversion; it returns
1.404 + * {@code false} otherwise. If this {@code Class} object
1.405 + * represents an interface, this method returns {@code true} if the
1.406 + * class or any superclass of the specified {@code Object} argument
1.407 + * implements this interface; it returns {@code false} otherwise. If
1.408 + * this {@code Class} object represents a primitive type, this method
1.409 + * returns {@code false}.
1.410 + *
1.411 + * @param obj the object to check
1.412 + * @return true if {@code obj} is an instance of this class
1.413 + *
1.414 + * @since JDK1.1
1.415 + */
1.416 + public native boolean isInstance(Object obj);
1.417 +
1.418 +
1.419 + /**
1.420 + * Determines if the class or interface represented by this
1.421 + * {@code Class} object is either the same as, or is a superclass or
1.422 + * superinterface of, the class or interface represented by the specified
1.423 + * {@code Class} parameter. It returns {@code true} if so;
1.424 + * otherwise it returns {@code false}. If this {@code Class}
1.425 + * object represents a primitive type, this method returns
1.426 + * {@code true} if the specified {@code Class} parameter is
1.427 + * exactly this {@code Class} object; otherwise it returns
1.428 + * {@code false}.
1.429 + *
1.430 + * <p> Specifically, this method tests whether the type represented by the
1.431 + * specified {@code Class} parameter can be converted to the type
1.432 + * represented by this {@code Class} object via an identity conversion
1.433 + * or via a widening reference conversion. See <em>The Java Language
1.434 + * Specification</em>, sections 5.1.1 and 5.1.4 , for details.
1.435 + *
1.436 + * @param cls the {@code Class} object to be checked
1.437 + * @return the {@code boolean} value indicating whether objects of the
1.438 + * type {@code cls} can be assigned to objects of this class
1.439 + * @exception NullPointerException if the specified Class parameter is
1.440 + * null.
1.441 + * @since JDK1.1
1.442 + */
1.443 + public native boolean isAssignableFrom(Class<?> cls);
1.444 +
1.445 +
1.446 + /**
1.447 + * Determines if the specified {@code Class} object represents an
1.448 + * interface type.
1.449 + *
1.450 + * @return {@code true} if this object represents an interface;
1.451 + * {@code false} otherwise.
1.452 + */
1.453 + public native boolean isInterface();
1.454 +
1.455 +
1.456 + /**
1.457 + * Determines if this {@code Class} object represents an array class.
1.458 + *
1.459 + * @return {@code true} if this object represents an array class;
1.460 + * {@code false} otherwise.
1.461 + * @since JDK1.1
1.462 + */
1.463 + public native boolean isArray();
1.464 +
1.465 +
1.466 + /**
1.467 + * Determines if the specified {@code Class} object represents a
1.468 + * primitive type.
1.469 + *
1.470 + * <p> There are nine predefined {@code Class} objects to represent
1.471 + * the eight primitive types and void. These are created by the Java
1.472 + * Virtual Machine, and have the same names as the primitive types that
1.473 + * they represent, namely {@code boolean}, {@code byte},
1.474 + * {@code char}, {@code short}, {@code int},
1.475 + * {@code long}, {@code float}, and {@code double}.
1.476 + *
1.477 + * <p> These objects may only be accessed via the following public static
1.478 + * final variables, and are the only {@code Class} objects for which
1.479 + * this method returns {@code true}.
1.480 + *
1.481 + * @return true if and only if this class represents a primitive type
1.482 + *
1.483 + * @see java.lang.Boolean#TYPE
1.484 + * @see java.lang.Character#TYPE
1.485 + * @see java.lang.Byte#TYPE
1.486 + * @see java.lang.Short#TYPE
1.487 + * @see java.lang.Integer#TYPE
1.488 + * @see java.lang.Long#TYPE
1.489 + * @see java.lang.Float#TYPE
1.490 + * @see java.lang.Double#TYPE
1.491 + * @see java.lang.Void#TYPE
1.492 + * @since JDK1.1
1.493 + */
1.494 + public native boolean isPrimitive();
1.495 +
1.496 + /**
1.497 + * Returns true if this {@code Class} object represents an annotation
1.498 + * type. Note that if this method returns true, {@link #isInterface()}
1.499 + * would also return true, as all annotation types are also interfaces.
1.500 + *
1.501 + * @return {@code true} if this class object represents an annotation
1.502 + * type; {@code false} otherwise
1.503 + * @since 1.5
1.504 + */
1.505 + public boolean isAnnotation() {
1.506 + return (getModifiers() & ANNOTATION) != 0;
1.507 + }
1.508 +
1.509 + /**
1.510 + * Returns {@code true} if this class is a synthetic class;
1.511 + * returns {@code false} otherwise.
1.512 + * @return {@code true} if and only if this class is a synthetic class as
1.513 + * defined by the Java Language Specification.
1.514 + * @since 1.5
1.515 + */
1.516 + public boolean isSynthetic() {
1.517 + return (getModifiers() & SYNTHETIC) != 0;
1.518 + }
1.519 +
1.520 + /**
1.521 + * Returns the name of the entity (class, interface, array class,
1.522 + * primitive type, or void) represented by this {@code Class} object,
1.523 + * as a {@code String}.
1.524 + *
1.525 + * <p> If this class object represents a reference type that is not an
1.526 + * array type then the binary name of the class is returned, as specified
1.527 + * by
1.528 + * <cite>The Java™ Language Specification</cite>.
1.529 + *
1.530 + * <p> If this class object represents a primitive type or void, then the
1.531 + * name returned is a {@code String} equal to the Java language
1.532 + * keyword corresponding to the primitive type or void.
1.533 + *
1.534 + * <p> If this class object represents a class of arrays, then the internal
1.535 + * form of the name consists of the name of the element type preceded by
1.536 + * one or more '{@code [}' characters representing the depth of the array
1.537 + * nesting. The encoding of element type names is as follows:
1.538 + *
1.539 + * <blockquote><table summary="Element types and encodings">
1.540 + * <tr><th> Element Type <th> <th> Encoding
1.541 + * <tr><td> boolean <td> <td align=center> Z
1.542 + * <tr><td> byte <td> <td align=center> B
1.543 + * <tr><td> char <td> <td align=center> C
1.544 + * <tr><td> class or interface
1.545 + * <td> <td align=center> L<i>classname</i>;
1.546 + * <tr><td> double <td> <td align=center> D
1.547 + * <tr><td> float <td> <td align=center> F
1.548 + * <tr><td> int <td> <td align=center> I
1.549 + * <tr><td> long <td> <td align=center> J
1.550 + * <tr><td> short <td> <td align=center> S
1.551 + * </table></blockquote>
1.552 + *
1.553 + * <p> The class or interface name <i>classname</i> is the binary name of
1.554 + * the class specified above.
1.555 + *
1.556 + * <p> Examples:
1.557 + * <blockquote><pre>
1.558 + * String.class.getName()
1.559 + * returns "java.lang.String"
1.560 + * byte.class.getName()
1.561 + * returns "byte"
1.562 + * (new Object[3]).getClass().getName()
1.563 + * returns "[Ljava.lang.Object;"
1.564 + * (new int[3][4][5][6][7][8][9]).getClass().getName()
1.565 + * returns "[[[[[[[I"
1.566 + * </pre></blockquote>
1.567 + *
1.568 + * @return the name of the class or interface
1.569 + * represented by this object.
1.570 + */
1.571 + public String getName() {
1.572 + String name = this.name;
1.573 + if (name == null)
1.574 + this.name = name = getName0();
1.575 + return name;
1.576 + }
1.577 +
1.578 + // cache the name to reduce the number of calls into the VM
1.579 + private transient String name;
1.580 + private native String getName0();
1.581 +
1.582 + /**
1.583 + * Returns the class loader for the class. Some implementations may use
1.584 + * null to represent the bootstrap class loader. This method will return
1.585 + * null in such implementations if this class was loaded by the bootstrap
1.586 + * class loader.
1.587 + *
1.588 + * <p> If a security manager is present, and the caller's class loader is
1.589 + * not null and the caller's class loader is not the same as or an ancestor of
1.590 + * the class loader for the class whose class loader is requested, then
1.591 + * this method calls the security manager's {@code checkPermission}
1.592 + * method with a {@code RuntimePermission("getClassLoader")}
1.593 + * permission to ensure it's ok to access the class loader for the class.
1.594 + *
1.595 + * <p>If this object
1.596 + * represents a primitive type or void, null is returned.
1.597 + *
1.598 + * @return the class loader that loaded the class or interface
1.599 + * represented by this object.
1.600 + * @throws SecurityException
1.601 + * if a security manager exists and its
1.602 + * {@code checkPermission} method denies
1.603 + * access to the class loader for the class.
1.604 + * @see java.lang.ClassLoader
1.605 + * @see SecurityManager#checkPermission
1.606 + * @see java.lang.RuntimePermission
1.607 + */
1.608 + public ClassLoader getClassLoader() {
1.609 + ClassLoader cl = getClassLoader0();
1.610 + if (cl == null)
1.611 + return null;
1.612 + SecurityManager sm = System.getSecurityManager();
1.613 + if (sm != null) {
1.614 + ClassLoader ccl = ClassLoader.getCallerClassLoader();
1.615 + if (ccl != null && ccl != cl && !cl.isAncestor(ccl)) {
1.616 + sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
1.617 + }
1.618 + }
1.619 + return cl;
1.620 + }
1.621 +
1.622 + // Package-private to allow ClassLoader access
1.623 + native ClassLoader getClassLoader0();
1.624 +
1.625 +
1.626 + /**
1.627 + * Returns an array of {@code TypeVariable} objects that represent the
1.628 + * type variables declared by the generic declaration represented by this
1.629 + * {@code GenericDeclaration} object, in declaration order. Returns an
1.630 + * array of length 0 if the underlying generic declaration declares no type
1.631 + * variables.
1.632 + *
1.633 + * @return an array of {@code TypeVariable} objects that represent
1.634 + * the type variables declared by this generic declaration
1.635 + * @throws java.lang.reflect.GenericSignatureFormatError if the generic
1.636 + * signature of this generic declaration does not conform to
1.637 + * the format specified in
1.638 + * <cite>The Java™ Virtual Machine Specification</cite>
1.639 + * @since 1.5
1.640 + */
1.641 + public TypeVariable<Class<T>>[] getTypeParameters() {
1.642 + if (getGenericSignature() != null)
1.643 + return (TypeVariable<Class<T>>[])getGenericInfo().getTypeParameters();
1.644 + else
1.645 + return (TypeVariable<Class<T>>[])new TypeVariable<?>[0];
1.646 + }
1.647 +
1.648 +
1.649 + /**
1.650 + * Returns the {@code Class} representing the superclass of the entity
1.651 + * (class, interface, primitive type or void) represented by this
1.652 + * {@code Class}. If this {@code Class} represents either the
1.653 + * {@code Object} class, an interface, a primitive type, or void, then
1.654 + * null is returned. If this object represents an array class then the
1.655 + * {@code Class} object representing the {@code Object} class is
1.656 + * returned.
1.657 + *
1.658 + * @return the superclass of the class represented by this object.
1.659 + */
1.660 + public native Class<? super T> getSuperclass();
1.661 +
1.662 +
1.663 + /**
1.664 + * Returns the {@code Type} representing the direct superclass of
1.665 + * the entity (class, interface, primitive type or void) represented by
1.666 + * this {@code Class}.
1.667 + *
1.668 + * <p>If the superclass is a parameterized type, the {@code Type}
1.669 + * object returned must accurately reflect the actual type
1.670 + * parameters used in the source code. The parameterized type
1.671 + * representing the superclass is created if it had not been
1.672 + * created before. See the declaration of {@link
1.673 + * java.lang.reflect.ParameterizedType ParameterizedType} for the
1.674 + * semantics of the creation process for parameterized types. If
1.675 + * this {@code Class} represents either the {@code Object}
1.676 + * class, an interface, a primitive type, or void, then null is
1.677 + * returned. If this object represents an array class then the
1.678 + * {@code Class} object representing the {@code Object} class is
1.679 + * returned.
1.680 + *
1.681 + * @throws java.lang.reflect.GenericSignatureFormatError if the generic
1.682 + * class signature does not conform to the format specified in
1.683 + * <cite>The Java™ Virtual Machine Specification</cite>
1.684 + * @throws TypeNotPresentException if the generic superclass
1.685 + * refers to a non-existent type declaration
1.686 + * @throws java.lang.reflect.MalformedParameterizedTypeException if the
1.687 + * generic superclass refers to a parameterized type that cannot be
1.688 + * instantiated for any reason
1.689 + * @return the superclass of the class represented by this object
1.690 + * @since 1.5
1.691 + */
1.692 + public Type getGenericSuperclass() {
1.693 + if (getGenericSignature() != null) {
1.694 + // Historical irregularity:
1.695 + // Generic signature marks interfaces with superclass = Object
1.696 + // but this API returns null for interfaces
1.697 + if (isInterface())
1.698 + return null;
1.699 + return getGenericInfo().getSuperclass();
1.700 + } else
1.701 + return getSuperclass();
1.702 + }
1.703 +
1.704 + /**
1.705 + * Gets the package for this class. The class loader of this class is used
1.706 + * to find the package. If the class was loaded by the bootstrap class
1.707 + * loader the set of packages loaded from CLASSPATH is searched to find the
1.708 + * package of the class. Null is returned if no package object was created
1.709 + * by the class loader of this class.
1.710 + *
1.711 + * <p> Packages have attributes for versions and specifications only if the
1.712 + * information was defined in the manifests that accompany the classes, and
1.713 + * if the class loader created the package instance with the attributes
1.714 + * from the manifest.
1.715 + *
1.716 + * @return the package of the class, or null if no package
1.717 + * information is available from the archive or codebase.
1.718 + */
1.719 + public Package getPackage() {
1.720 + return Package.getPackage(this);
1.721 + }
1.722 +
1.723 +
1.724 + /**
1.725 + * Determines the interfaces implemented by the class or interface
1.726 + * represented by this object.
1.727 + *
1.728 + * <p> If this object represents a class, the return value is an array
1.729 + * containing objects representing all interfaces implemented by the
1.730 + * class. The order of the interface objects in the array corresponds to
1.731 + * the order of the interface names in the {@code implements} clause
1.732 + * of the declaration of the class represented by this object. For
1.733 + * example, given the declaration:
1.734 + * <blockquote>
1.735 + * {@code class Shimmer implements FloorWax, DessertTopping { ... }}
1.736 + * </blockquote>
1.737 + * suppose the value of {@code s} is an instance of
1.738 + * {@code Shimmer}; the value of the expression:
1.739 + * <blockquote>
1.740 + * {@code s.getClass().getInterfaces()[0]}
1.741 + * </blockquote>
1.742 + * is the {@code Class} object that represents interface
1.743 + * {@code FloorWax}; and the value of:
1.744 + * <blockquote>
1.745 + * {@code s.getClass().getInterfaces()[1]}
1.746 + * </blockquote>
1.747 + * is the {@code Class} object that represents interface
1.748 + * {@code DessertTopping}.
1.749 + *
1.750 + * <p> If this object represents an interface, the array contains objects
1.751 + * representing all interfaces extended by the interface. The order of the
1.752 + * interface objects in the array corresponds to the order of the interface
1.753 + * names in the {@code extends} clause of the declaration of the
1.754 + * interface represented by this object.
1.755 + *
1.756 + * <p> If this object represents a class or interface that implements no
1.757 + * interfaces, the method returns an array of length 0.
1.758 + *
1.759 + * <p> If this object represents a primitive type or void, the method
1.760 + * returns an array of length 0.
1.761 + *
1.762 + * @return an array of interfaces implemented by this class.
1.763 + */
1.764 + public native Class<?>[] getInterfaces();
1.765 +
1.766 + /**
1.767 + * Returns the {@code Type}s representing the interfaces
1.768 + * directly implemented by the class or interface represented by
1.769 + * this object.
1.770 + *
1.771 + * <p>If a superinterface is a parameterized type, the
1.772 + * {@code Type} object returned for it must accurately reflect
1.773 + * the actual type parameters used in the source code. The
1.774 + * parameterized type representing each superinterface is created
1.775 + * if it had not been created before. See the declaration of
1.776 + * {@link java.lang.reflect.ParameterizedType ParameterizedType}
1.777 + * for the semantics of the creation process for parameterized
1.778 + * types.
1.779 + *
1.780 + * <p> If this object represents a class, the return value is an
1.781 + * array containing objects representing all interfaces
1.782 + * implemented by the class. The order of the interface objects in
1.783 + * the array corresponds to the order of the interface names in
1.784 + * the {@code implements} clause of the declaration of the class
1.785 + * represented by this object. In the case of an array class, the
1.786 + * interfaces {@code Cloneable} and {@code Serializable} are
1.787 + * returned in that order.
1.788 + *
1.789 + * <p>If this object represents an interface, the array contains
1.790 + * objects representing all interfaces directly extended by the
1.791 + * interface. The order of the interface objects in the array
1.792 + * corresponds to the order of the interface names in the
1.793 + * {@code extends} clause of the declaration of the interface
1.794 + * represented by this object.
1.795 + *
1.796 + * <p>If this object represents a class or interface that
1.797 + * implements no interfaces, the method returns an array of length
1.798 + * 0.
1.799 + *
1.800 + * <p>If this object represents a primitive type or void, the
1.801 + * method returns an array of length 0.
1.802 + *
1.803 + * @throws java.lang.reflect.GenericSignatureFormatError
1.804 + * if the generic class signature does not conform to the format
1.805 + * specified in
1.806 + * <cite>The Java™ Virtual Machine Specification</cite>
1.807 + * @throws TypeNotPresentException if any of the generic
1.808 + * superinterfaces refers to a non-existent type declaration
1.809 + * @throws java.lang.reflect.MalformedParameterizedTypeException
1.810 + * if any of the generic superinterfaces refer to a parameterized
1.811 + * type that cannot be instantiated for any reason
1.812 + * @return an array of interfaces implemented by this class
1.813 + * @since 1.5
1.814 + */
1.815 + public Type[] getGenericInterfaces() {
1.816 + if (getGenericSignature() != null)
1.817 + return getGenericInfo().getSuperInterfaces();
1.818 + else
1.819 + return getInterfaces();
1.820 + }
1.821 +
1.822 +
1.823 + /**
1.824 + * Returns the {@code Class} representing the component type of an
1.825 + * array. If this class does not represent an array class this method
1.826 + * returns null.
1.827 + *
1.828 + * @return the {@code Class} representing the component type of this
1.829 + * class if this class is an array
1.830 + * @see java.lang.reflect.Array
1.831 + * @since JDK1.1
1.832 + */
1.833 + public native Class<?> getComponentType();
1.834 +
1.835 +
1.836 + /**
1.837 + * Returns the Java language modifiers for this class or interface, encoded
1.838 + * in an integer. The modifiers consist of the Java Virtual Machine's
1.839 + * constants for {@code public}, {@code protected},
1.840 + * {@code private}, {@code final}, {@code static},
1.841 + * {@code abstract} and {@code interface}; they should be decoded
1.842 + * using the methods of class {@code Modifier}.
1.843 + *
1.844 + * <p> If the underlying class is an array class, then its
1.845 + * {@code public}, {@code private} and {@code protected}
1.846 + * modifiers are the same as those of its component type. If this
1.847 + * {@code Class} represents a primitive type or void, its
1.848 + * {@code public} modifier is always {@code true}, and its
1.849 + * {@code protected} and {@code private} modifiers are always
1.850 + * {@code false}. If this object represents an array class, a
1.851 + * primitive type or void, then its {@code final} modifier is always
1.852 + * {@code true} and its interface modifier is always
1.853 + * {@code false}. The values of its other modifiers are not determined
1.854 + * by this specification.
1.855 + *
1.856 + * <p> The modifier encodings are defined in <em>The Java Virtual Machine
1.857 + * Specification</em>, table 4.1.
1.858 + *
1.859 + * @return the {@code int} representing the modifiers for this class
1.860 + * @see java.lang.reflect.Modifier
1.861 + * @since JDK1.1
1.862 + */
1.863 + public native int getModifiers();
1.864 +
1.865 +
1.866 + /**
1.867 + * Gets the signers of this class.
1.868 + *
1.869 + * @return the signers of this class, or null if there are no signers. In
1.870 + * particular, this method returns null if this object represents
1.871 + * a primitive type or void.
1.872 + * @since JDK1.1
1.873 + */
1.874 + public native Object[] getSigners();
1.875 +
1.876 +
1.877 + /**
1.878 + * Set the signers of this class.
1.879 + */
1.880 + native void setSigners(Object[] signers);
1.881 +
1.882 +
1.883 + /**
1.884 + * If this {@code Class} object represents a local or anonymous
1.885 + * class within a method, returns a {@link
1.886 + * java.lang.reflect.Method Method} object representing the
1.887 + * immediately enclosing method of the underlying class. Returns
1.888 + * {@code null} otherwise.
1.889 + *
1.890 + * In particular, this method returns {@code null} if the underlying
1.891 + * class is a local or anonymous class immediately enclosed by a type
1.892 + * declaration, instance initializer or static initializer.
1.893 + *
1.894 + * @return the immediately enclosing method of the underlying class, if
1.895 + * that class is a local or anonymous class; otherwise {@code null}.
1.896 + * @since 1.5
1.897 + */
1.898 + public Method getEnclosingMethod() {
1.899 + EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
1.900 +
1.901 + if (enclosingInfo == null)
1.902 + return null;
1.903 + else {
1.904 + if (!enclosingInfo.isMethod())
1.905 + return null;
1.906 +
1.907 + MethodRepository typeInfo = MethodRepository.make(enclosingInfo.getDescriptor(),
1.908 + getFactory());
1.909 + Class<?> returnType = toClass(typeInfo.getReturnType());
1.910 + Type [] parameterTypes = typeInfo.getParameterTypes();
1.911 + Class<?>[] parameterClasses = new Class<?>[parameterTypes.length];
1.912 +
1.913 + // Convert Types to Classes; returned types *should*
1.914 + // be class objects since the methodDescriptor's used
1.915 + // don't have generics information
1.916 + for(int i = 0; i < parameterClasses.length; i++)
1.917 + parameterClasses[i] = toClass(parameterTypes[i]);
1.918 +
1.919 + /*
1.920 + * Loop over all declared methods; match method name,
1.921 + * number of and type of parameters, *and* return
1.922 + * type. Matching return type is also necessary
1.923 + * because of covariant returns, etc.
1.924 + */
1.925 + for(Method m: enclosingInfo.getEnclosingClass().getDeclaredMethods()) {
1.926 + if (m.getName().equals(enclosingInfo.getName()) ) {
1.927 + Class<?>[] candidateParamClasses = m.getParameterTypes();
1.928 + if (candidateParamClasses.length == parameterClasses.length) {
1.929 + boolean matches = true;
1.930 + for(int i = 0; i < candidateParamClasses.length; i++) {
1.931 + if (!candidateParamClasses[i].equals(parameterClasses[i])) {
1.932 + matches = false;
1.933 + break;
1.934 + }
1.935 + }
1.936 +
1.937 + if (matches) { // finally, check return type
1.938 + if (m.getReturnType().equals(returnType) )
1.939 + return m;
1.940 + }
1.941 + }
1.942 + }
1.943 + }
1.944 +
1.945 + throw new InternalError("Enclosing method not found");
1.946 + }
1.947 + }
1.948 +
1.949 + private native Object[] getEnclosingMethod0();
1.950 +
1.951 + private EnclosingMethodInfo getEnclosingMethodInfo() {
1.952 + Object[] enclosingInfo = getEnclosingMethod0();
1.953 + if (enclosingInfo == null)
1.954 + return null;
1.955 + else {
1.956 + return new EnclosingMethodInfo(enclosingInfo);
1.957 + }
1.958 + }
1.959 +
1.960 + private final static class EnclosingMethodInfo {
1.961 + private Class<?> enclosingClass;
1.962 + private String name;
1.963 + private String descriptor;
1.964 +
1.965 + private EnclosingMethodInfo(Object[] enclosingInfo) {
1.966 + if (enclosingInfo.length != 3)
1.967 + throw new InternalError("Malformed enclosing method information");
1.968 + try {
1.969 + // The array is expected to have three elements:
1.970 +
1.971 + // the immediately enclosing class
1.972 + enclosingClass = (Class<?>) enclosingInfo[0];
1.973 + assert(enclosingClass != null);
1.974 +
1.975 + // the immediately enclosing method or constructor's
1.976 + // name (can be null).
1.977 + name = (String) enclosingInfo[1];
1.978 +
1.979 + // the immediately enclosing method or constructor's
1.980 + // descriptor (null iff name is).
1.981 + descriptor = (String) enclosingInfo[2];
1.982 + assert((name != null && descriptor != null) || name == descriptor);
1.983 + } catch (ClassCastException cce) {
1.984 + throw new InternalError("Invalid type in enclosing method information");
1.985 + }
1.986 + }
1.987 +
1.988 + boolean isPartial() {
1.989 + return enclosingClass == null || name == null || descriptor == null;
1.990 + }
1.991 +
1.992 + boolean isConstructor() { return !isPartial() && "<init>".equals(name); }
1.993 +
1.994 + boolean isMethod() { return !isPartial() && !isConstructor() && !"<clinit>".equals(name); }
1.995 +
1.996 + Class<?> getEnclosingClass() { return enclosingClass; }
1.997 +
1.998 + String getName() { return name; }
1.999 +
1.1000 + String getDescriptor() { return descriptor; }
1.1001 +
1.1002 + }
1.1003 +
1.1004 + private static Class<?> toClass(Type o) {
1.1005 + if (o instanceof GenericArrayType)
1.1006 + return Array.newInstance(toClass(((GenericArrayType)o).getGenericComponentType()),
1.1007 + 0)
1.1008 + .getClass();
1.1009 + return (Class<?>)o;
1.1010 + }
1.1011 +
1.1012 + /**
1.1013 + * If this {@code Class} object represents a local or anonymous
1.1014 + * class within a constructor, returns a {@link
1.1015 + * java.lang.reflect.Constructor Constructor} object representing
1.1016 + * the immediately enclosing constructor of the underlying
1.1017 + * class. Returns {@code null} otherwise. In particular, this
1.1018 + * method returns {@code null} if the underlying class is a local
1.1019 + * or anonymous class immediately enclosed by a type declaration,
1.1020 + * instance initializer or static initializer.
1.1021 + *
1.1022 + * @return the immediately enclosing constructor of the underlying class, if
1.1023 + * that class is a local or anonymous class; otherwise {@code null}.
1.1024 + * @since 1.5
1.1025 + */
1.1026 + public Constructor<?> getEnclosingConstructor() {
1.1027 + EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
1.1028 +
1.1029 + if (enclosingInfo == null)
1.1030 + return null;
1.1031 + else {
1.1032 + if (!enclosingInfo.isConstructor())
1.1033 + return null;
1.1034 +
1.1035 + ConstructorRepository typeInfo = ConstructorRepository.make(enclosingInfo.getDescriptor(),
1.1036 + getFactory());
1.1037 + Type [] parameterTypes = typeInfo.getParameterTypes();
1.1038 + Class<?>[] parameterClasses = new Class<?>[parameterTypes.length];
1.1039 +
1.1040 + // Convert Types to Classes; returned types *should*
1.1041 + // be class objects since the methodDescriptor's used
1.1042 + // don't have generics information
1.1043 + for(int i = 0; i < parameterClasses.length; i++)
1.1044 + parameterClasses[i] = toClass(parameterTypes[i]);
1.1045 +
1.1046 + /*
1.1047 + * Loop over all declared constructors; match number
1.1048 + * of and type of parameters.
1.1049 + */
1.1050 + for(Constructor<?> c: enclosingInfo.getEnclosingClass().getDeclaredConstructors()) {
1.1051 + Class<?>[] candidateParamClasses = c.getParameterTypes();
1.1052 + if (candidateParamClasses.length == parameterClasses.length) {
1.1053 + boolean matches = true;
1.1054 + for(int i = 0; i < candidateParamClasses.length; i++) {
1.1055 + if (!candidateParamClasses[i].equals(parameterClasses[i])) {
1.1056 + matches = false;
1.1057 + break;
1.1058 + }
1.1059 + }
1.1060 +
1.1061 + if (matches)
1.1062 + return c;
1.1063 + }
1.1064 + }
1.1065 +
1.1066 + throw new InternalError("Enclosing constructor not found");
1.1067 + }
1.1068 + }
1.1069 +
1.1070 +
1.1071 + /**
1.1072 + * If the class or interface represented by this {@code Class} object
1.1073 + * is a member of another class, returns the {@code Class} object
1.1074 + * representing the class in which it was declared. This method returns
1.1075 + * null if this class or interface is not a member of any other class. If
1.1076 + * this {@code Class} object represents an array class, a primitive
1.1077 + * type, or void,then this method returns null.
1.1078 + *
1.1079 + * @return the declaring class for this class
1.1080 + * @since JDK1.1
1.1081 + */
1.1082 + public native Class<?> getDeclaringClass();
1.1083 +
1.1084 +
1.1085 + /**
1.1086 + * Returns the immediately enclosing class of the underlying
1.1087 + * class. If the underlying class is a top level class this
1.1088 + * method returns {@code null}.
1.1089 + * @return the immediately enclosing class of the underlying class
1.1090 + * @since 1.5
1.1091 + */
1.1092 + public Class<?> getEnclosingClass() {
1.1093 + // There are five kinds of classes (or interfaces):
1.1094 + // a) Top level classes
1.1095 + // b) Nested classes (static member classes)
1.1096 + // c) Inner classes (non-static member classes)
1.1097 + // d) Local classes (named classes declared within a method)
1.1098 + // e) Anonymous classes
1.1099 +
1.1100 +
1.1101 + // JVM Spec 4.8.6: A class must have an EnclosingMethod
1.1102 + // attribute if and only if it is a local class or an
1.1103 + // anonymous class.
1.1104 + EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
1.1105 +
1.1106 + if (enclosingInfo == null) {
1.1107 + // This is a top level or a nested class or an inner class (a, b, or c)
1.1108 + return getDeclaringClass();
1.1109 + } else {
1.1110 + Class<?> enclosingClass = enclosingInfo.getEnclosingClass();
1.1111 + // This is a local class or an anonymous class (d or e)
1.1112 + if (enclosingClass == this || enclosingClass == null)
1.1113 + throw new InternalError("Malformed enclosing method information");
1.1114 + else
1.1115 + return enclosingClass;
1.1116 + }
1.1117 + }
1.1118 +
1.1119 + /**
1.1120 + * Returns the simple name of the underlying class as given in the
1.1121 + * source code. Returns an empty string if the underlying class is
1.1122 + * anonymous.
1.1123 + *
1.1124 + * <p>The simple name of an array is the simple name of the
1.1125 + * component type with "[]" appended. In particular the simple
1.1126 + * name of an array whose component type is anonymous is "[]".
1.1127 + *
1.1128 + * @return the simple name of the underlying class
1.1129 + * @since 1.5
1.1130 + */
1.1131 + public String getSimpleName() {
1.1132 + if (isArray())
1.1133 + return getComponentType().getSimpleName()+"[]";
1.1134 +
1.1135 + String simpleName = getSimpleBinaryName();
1.1136 + if (simpleName == null) { // top level class
1.1137 + simpleName = getName();
1.1138 + return simpleName.substring(simpleName.lastIndexOf(".")+1); // strip the package name
1.1139 + }
1.1140 + // According to JLS3 "Binary Compatibility" (13.1) the binary
1.1141 + // name of non-package classes (not top level) is the binary
1.1142 + // name of the immediately enclosing class followed by a '$' followed by:
1.1143 + // (for nested and inner classes): the simple name.
1.1144 + // (for local classes): 1 or more digits followed by the simple name.
1.1145 + // (for anonymous classes): 1 or more digits.
1.1146 +
1.1147 + // Since getSimpleBinaryName() will strip the binary name of
1.1148 + // the immediatly enclosing class, we are now looking at a
1.1149 + // string that matches the regular expression "\$[0-9]*"
1.1150 + // followed by a simple name (considering the simple of an
1.1151 + // anonymous class to be the empty string).
1.1152 +
1.1153 + // Remove leading "\$[0-9]*" from the name
1.1154 + int length = simpleName.length();
1.1155 + if (length < 1 || simpleName.charAt(0) != '$')
1.1156 + throw new InternalError("Malformed class name");
1.1157 + int index = 1;
1.1158 + while (index < length && isAsciiDigit(simpleName.charAt(index)))
1.1159 + index++;
1.1160 + // Eventually, this is the empty string iff this is an anonymous class
1.1161 + return simpleName.substring(index);
1.1162 + }
1.1163 +
1.1164 + /**
1.1165 + * Character.isDigit answers {@code true} to some non-ascii
1.1166 + * digits. This one does not.
1.1167 + */
1.1168 + private static boolean isAsciiDigit(char c) {
1.1169 + return '0' <= c && c <= '9';
1.1170 + }
1.1171 +
1.1172 + /**
1.1173 + * Returns the canonical name of the underlying class as
1.1174 + * defined by the Java Language Specification. Returns null if
1.1175 + * the underlying class does not have a canonical name (i.e., if
1.1176 + * it is a local or anonymous class or an array whose component
1.1177 + * type does not have a canonical name).
1.1178 + * @return the canonical name of the underlying class if it exists, and
1.1179 + * {@code null} otherwise.
1.1180 + * @since 1.5
1.1181 + */
1.1182 + public String getCanonicalName() {
1.1183 + if (isArray()) {
1.1184 + String canonicalName = getComponentType().getCanonicalName();
1.1185 + if (canonicalName != null)
1.1186 + return canonicalName + "[]";
1.1187 + else
1.1188 + return null;
1.1189 + }
1.1190 + if (isLocalOrAnonymousClass())
1.1191 + return null;
1.1192 + Class<?> enclosingClass = getEnclosingClass();
1.1193 + if (enclosingClass == null) { // top level class
1.1194 + return getName();
1.1195 + } else {
1.1196 + String enclosingName = enclosingClass.getCanonicalName();
1.1197 + if (enclosingName == null)
1.1198 + return null;
1.1199 + return enclosingName + "." + getSimpleName();
1.1200 + }
1.1201 + }
1.1202 +
1.1203 + /**
1.1204 + * Returns {@code true} if and only if the underlying class
1.1205 + * is an anonymous class.
1.1206 + *
1.1207 + * @return {@code true} if and only if this class is an anonymous class.
1.1208 + * @since 1.5
1.1209 + */
1.1210 + public boolean isAnonymousClass() {
1.1211 + return "".equals(getSimpleName());
1.1212 + }
1.1213 +
1.1214 + /**
1.1215 + * Returns {@code true} if and only if the underlying class
1.1216 + * is a local class.
1.1217 + *
1.1218 + * @return {@code true} if and only if this class is a local class.
1.1219 + * @since 1.5
1.1220 + */
1.1221 + public boolean isLocalClass() {
1.1222 + return isLocalOrAnonymousClass() && !isAnonymousClass();
1.1223 + }
1.1224 +
1.1225 + /**
1.1226 + * Returns {@code true} if and only if the underlying class
1.1227 + * is a member class.
1.1228 + *
1.1229 + * @return {@code true} if and only if this class is a member class.
1.1230 + * @since 1.5
1.1231 + */
1.1232 + public boolean isMemberClass() {
1.1233 + return getSimpleBinaryName() != null && !isLocalOrAnonymousClass();
1.1234 + }
1.1235 +
1.1236 + /**
1.1237 + * Returns the "simple binary name" of the underlying class, i.e.,
1.1238 + * the binary name without the leading enclosing class name.
1.1239 + * Returns {@code null} if the underlying class is a top level
1.1240 + * class.
1.1241 + */
1.1242 + private String getSimpleBinaryName() {
1.1243 + Class<?> enclosingClass = getEnclosingClass();
1.1244 + if (enclosingClass == null) // top level class
1.1245 + return null;
1.1246 + // Otherwise, strip the enclosing class' name
1.1247 + try {
1.1248 + return getName().substring(enclosingClass.getName().length());
1.1249 + } catch (IndexOutOfBoundsException ex) {
1.1250 + throw new InternalError("Malformed class name");
1.1251 + }
1.1252 + }
1.1253 +
1.1254 + /**
1.1255 + * Returns {@code true} if this is a local class or an anonymous
1.1256 + * class. Returns {@code false} otherwise.
1.1257 + */
1.1258 + private boolean isLocalOrAnonymousClass() {
1.1259 + // JVM Spec 4.8.6: A class must have an EnclosingMethod
1.1260 + // attribute if and only if it is a local class or an
1.1261 + // anonymous class.
1.1262 + return getEnclosingMethodInfo() != null;
1.1263 + }
1.1264 +
1.1265 + /**
1.1266 + * Returns an array containing {@code Class} objects representing all
1.1267 + * the public classes and interfaces that are members of the class
1.1268 + * represented by this {@code Class} object. This includes public
1.1269 + * class and interface members inherited from superclasses and public class
1.1270 + * and interface members declared by the class. This method returns an
1.1271 + * array of length 0 if this {@code Class} object has no public member
1.1272 + * classes or interfaces. This method also returns an array of length 0 if
1.1273 + * this {@code Class} object represents a primitive type, an array
1.1274 + * class, or void.
1.1275 + *
1.1276 + * @return the array of {@code Class} objects representing the public
1.1277 + * members of this class
1.1278 + * @exception SecurityException
1.1279 + * If a security manager, <i>s</i>, is present and any of the
1.1280 + * following conditions is met:
1.1281 + *
1.1282 + * <ul>
1.1283 + *
1.1284 + * <li> invocation of
1.1285 + * {@link SecurityManager#checkMemberAccess
1.1286 + * s.checkMemberAccess(this, Member.PUBLIC)} method
1.1287 + * denies access to the classes within this class
1.1288 + *
1.1289 + * <li> the caller's class loader is not the same as or an
1.1290 + * ancestor of the class loader for the current class and
1.1291 + * invocation of {@link SecurityManager#checkPackageAccess
1.1292 + * s.checkPackageAccess()} denies access to the package
1.1293 + * of this class
1.1294 + *
1.1295 + * </ul>
1.1296 + *
1.1297 + * @since JDK1.1
1.1298 + */
1.1299 + public Class<?>[] getClasses() {
1.1300 + // be very careful not to change the stack depth of this
1.1301 + // checkMemberAccess call for security reasons
1.1302 + // see java.lang.SecurityManager.checkMemberAccess
1.1303 + checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
1.1304 +
1.1305 + // Privileged so this implementation can look at DECLARED classes,
1.1306 + // something the caller might not have privilege to do. The code here
1.1307 + // is allowed to look at DECLARED classes because (1) it does not hand
1.1308 + // out anything other than public members and (2) public member access
1.1309 + // has already been ok'd by the SecurityManager.
1.1310 +
1.1311 + return java.security.AccessController.doPrivileged(
1.1312 + new java.security.PrivilegedAction<Class<?>[]>() {
1.1313 + public Class[] run() {
1.1314 + List<Class<?>> list = new ArrayList<>();
1.1315 + Class<?> currentClass = Class.this;
1.1316 + while (currentClass != null) {
1.1317 + Class<?>[] members = currentClass.getDeclaredClasses();
1.1318 + for (int i = 0; i < members.length; i++) {
1.1319 + if (Modifier.isPublic(members[i].getModifiers())) {
1.1320 + list.add(members[i]);
1.1321 + }
1.1322 + }
1.1323 + currentClass = currentClass.getSuperclass();
1.1324 + }
1.1325 + return list.toArray(new Class[0]);
1.1326 + }
1.1327 + });
1.1328 + }
1.1329 +
1.1330 +
1.1331 + /**
1.1332 + * Returns an array containing {@code Field} objects reflecting all
1.1333 + * the accessible public fields of the class or interface represented by
1.1334 + * this {@code Class} object. The elements in the array returned are
1.1335 + * not sorted and are not in any particular order. This method returns an
1.1336 + * array of length 0 if the class or interface has no accessible public
1.1337 + * fields, or if it represents an array class, a primitive type, or void.
1.1338 + *
1.1339 + * <p> Specifically, if this {@code Class} object represents a class,
1.1340 + * this method returns the public fields of this class and of all its
1.1341 + * superclasses. If this {@code Class} object represents an
1.1342 + * interface, this method returns the fields of this interface and of all
1.1343 + * its superinterfaces.
1.1344 + *
1.1345 + * <p> The implicit length field for array class is not reflected by this
1.1346 + * method. User code should use the methods of class {@code Array} to
1.1347 + * manipulate arrays.
1.1348 + *
1.1349 + * <p> See <em>The Java Language Specification</em>, sections 8.2 and 8.3.
1.1350 + *
1.1351 + * @return the array of {@code Field} objects representing the
1.1352 + * public fields
1.1353 + * @exception SecurityException
1.1354 + * If a security manager, <i>s</i>, is present and any of the
1.1355 + * following conditions is met:
1.1356 + *
1.1357 + * <ul>
1.1358 + *
1.1359 + * <li> invocation of
1.1360 + * {@link SecurityManager#checkMemberAccess
1.1361 + * s.checkMemberAccess(this, Member.PUBLIC)} denies
1.1362 + * access to the fields within this class
1.1363 + *
1.1364 + * <li> the caller's class loader is not the same as or an
1.1365 + * ancestor of the class loader for the current class and
1.1366 + * invocation of {@link SecurityManager#checkPackageAccess
1.1367 + * s.checkPackageAccess()} denies access to the package
1.1368 + * of this class
1.1369 + *
1.1370 + * </ul>
1.1371 + *
1.1372 + * @since JDK1.1
1.1373 + */
1.1374 + public Field[] getFields() throws SecurityException {
1.1375 + // be very careful not to change the stack depth of this
1.1376 + // checkMemberAccess call for security reasons
1.1377 + // see java.lang.SecurityManager.checkMemberAccess
1.1378 + checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
1.1379 + return copyFields(privateGetPublicFields(null));
1.1380 + }
1.1381 +
1.1382 +
1.1383 + /**
1.1384 + * Returns an array containing {@code Method} objects reflecting all
1.1385 + * the public <em>member</em> methods of the class or interface represented
1.1386 + * by this {@code Class} object, including those declared by the class
1.1387 + * or interface and those inherited from superclasses and
1.1388 + * superinterfaces. Array classes return all the (public) member methods
1.1389 + * inherited from the {@code Object} class. The elements in the array
1.1390 + * returned are not sorted and are not in any particular order. This
1.1391 + * method returns an array of length 0 if this {@code Class} object
1.1392 + * represents a class or interface that has no public member methods, or if
1.1393 + * this {@code Class} object represents a primitive type or void.
1.1394 + *
1.1395 + * <p> The class initialization method {@code <clinit>} is not
1.1396 + * included in the returned array. If the class declares multiple public
1.1397 + * member methods with the same parameter types, they are all included in
1.1398 + * the returned array.
1.1399 + *
1.1400 + * <p> See <em>The Java Language Specification</em>, sections 8.2 and 8.4.
1.1401 + *
1.1402 + * @return the array of {@code Method} objects representing the
1.1403 + * public methods of this class
1.1404 + * @exception SecurityException
1.1405 + * If a security manager, <i>s</i>, is present and any of the
1.1406 + * following conditions is met:
1.1407 + *
1.1408 + * <ul>
1.1409 + *
1.1410 + * <li> invocation of
1.1411 + * {@link SecurityManager#checkMemberAccess
1.1412 + * s.checkMemberAccess(this, Member.PUBLIC)} denies
1.1413 + * access to the methods within this class
1.1414 + *
1.1415 + * <li> the caller's class loader is not the same as or an
1.1416 + * ancestor of the class loader for the current class and
1.1417 + * invocation of {@link SecurityManager#checkPackageAccess
1.1418 + * s.checkPackageAccess()} denies access to the package
1.1419 + * of this class
1.1420 + *
1.1421 + * </ul>
1.1422 + *
1.1423 + * @since JDK1.1
1.1424 + */
1.1425 + public Method[] getMethods() throws SecurityException {
1.1426 + // be very careful not to change the stack depth of this
1.1427 + // checkMemberAccess call for security reasons
1.1428 + // see java.lang.SecurityManager.checkMemberAccess
1.1429 + checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
1.1430 + return copyMethods(privateGetPublicMethods());
1.1431 + }
1.1432 +
1.1433 +
1.1434 + /**
1.1435 + * Returns an array containing {@code Constructor} objects reflecting
1.1436 + * all the public constructors of the class represented by this
1.1437 + * {@code Class} object. An array of length 0 is returned if the
1.1438 + * class has no public constructors, or if the class is an array class, or
1.1439 + * if the class reflects a primitive type or void.
1.1440 + *
1.1441 + * Note that while this method returns an array of {@code
1.1442 + * Constructor<T>} objects (that is an array of constructors from
1.1443 + * this class), the return type of this method is {@code
1.1444 + * Constructor<?>[]} and <em>not</em> {@code Constructor<T>[]} as
1.1445 + * might be expected. This less informative return type is
1.1446 + * necessary since after being returned from this method, the
1.1447 + * array could be modified to hold {@code Constructor} objects for
1.1448 + * different classes, which would violate the type guarantees of
1.1449 + * {@code Constructor<T>[]}.
1.1450 + *
1.1451 + * @return the array of {@code Constructor} objects representing the
1.1452 + * public constructors of this class
1.1453 + * @exception SecurityException
1.1454 + * If a security manager, <i>s</i>, is present and any of the
1.1455 + * following conditions is met:
1.1456 + *
1.1457 + * <ul>
1.1458 + *
1.1459 + * <li> invocation of
1.1460 + * {@link SecurityManager#checkMemberAccess
1.1461 + * s.checkMemberAccess(this, Member.PUBLIC)} denies
1.1462 + * access to the constructors within this class
1.1463 + *
1.1464 + * <li> the caller's class loader is not the same as or an
1.1465 + * ancestor of the class loader for the current class and
1.1466 + * invocation of {@link SecurityManager#checkPackageAccess
1.1467 + * s.checkPackageAccess()} denies access to the package
1.1468 + * of this class
1.1469 + *
1.1470 + * </ul>
1.1471 + *
1.1472 + * @since JDK1.1
1.1473 + */
1.1474 + public Constructor<?>[] getConstructors() throws SecurityException {
1.1475 + // be very careful not to change the stack depth of this
1.1476 + // checkMemberAccess call for security reasons
1.1477 + // see java.lang.SecurityManager.checkMemberAccess
1.1478 + checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
1.1479 + return copyConstructors(privateGetDeclaredConstructors(true));
1.1480 + }
1.1481 +
1.1482 +
1.1483 + /**
1.1484 + * Returns a {@code Field} object that reflects the specified public
1.1485 + * member field of the class or interface represented by this
1.1486 + * {@code Class} object. The {@code name} parameter is a
1.1487 + * {@code String} specifying the simple name of the desired field.
1.1488 + *
1.1489 + * <p> The field to be reflected is determined by the algorithm that
1.1490 + * follows. Let C be the class represented by this object:
1.1491 + * <OL>
1.1492 + * <LI> If C declares a public field with the name specified, that is the
1.1493 + * field to be reflected.</LI>
1.1494 + * <LI> If no field was found in step 1 above, this algorithm is applied
1.1495 + * recursively to each direct superinterface of C. The direct
1.1496 + * superinterfaces are searched in the order they were declared.</LI>
1.1497 + * <LI> If no field was found in steps 1 and 2 above, and C has a
1.1498 + * superclass S, then this algorithm is invoked recursively upon S.
1.1499 + * If C has no superclass, then a {@code NoSuchFieldException}
1.1500 + * is thrown.</LI>
1.1501 + * </OL>
1.1502 + *
1.1503 + * <p> See <em>The Java Language Specification</em>, sections 8.2 and 8.3.
1.1504 + *
1.1505 + * @param name the field name
1.1506 + * @return the {@code Field} object of this class specified by
1.1507 + * {@code name}
1.1508 + * @exception NoSuchFieldException if a field with the specified name is
1.1509 + * not found.
1.1510 + * @exception NullPointerException if {@code name} is {@code null}
1.1511 + * @exception SecurityException
1.1512 + * If a security manager, <i>s</i>, is present and any of the
1.1513 + * following conditions is met:
1.1514 + *
1.1515 + * <ul>
1.1516 + *
1.1517 + * <li> invocation of
1.1518 + * {@link SecurityManager#checkMemberAccess
1.1519 + * s.checkMemberAccess(this, Member.PUBLIC)} denies
1.1520 + * access to the field
1.1521 + *
1.1522 + * <li> the caller's class loader is not the same as or an
1.1523 + * ancestor of the class loader for the current class and
1.1524 + * invocation of {@link SecurityManager#checkPackageAccess
1.1525 + * s.checkPackageAccess()} denies access to the package
1.1526 + * of this class
1.1527 + *
1.1528 + * </ul>
1.1529 + *
1.1530 + * @since JDK1.1
1.1531 + */
1.1532 + public Field getField(String name)
1.1533 + throws NoSuchFieldException, SecurityException {
1.1534 + // be very careful not to change the stack depth of this
1.1535 + // checkMemberAccess call for security reasons
1.1536 + // see java.lang.SecurityManager.checkMemberAccess
1.1537 + checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
1.1538 + Field field = getField0(name);
1.1539 + if (field == null) {
1.1540 + throw new NoSuchFieldException(name);
1.1541 + }
1.1542 + return field;
1.1543 + }
1.1544 +
1.1545 +
1.1546 + /**
1.1547 + * Returns a {@code Method} object that reflects the specified public
1.1548 + * member method of the class or interface represented by this
1.1549 + * {@code Class} object. The {@code name} parameter is a
1.1550 + * {@code String} specifying the simple name of the desired method. The
1.1551 + * {@code parameterTypes} parameter is an array of {@code Class}
1.1552 + * objects that identify the method's formal parameter types, in declared
1.1553 + * order. If {@code parameterTypes} is {@code null}, it is
1.1554 + * treated as if it were an empty array.
1.1555 + *
1.1556 + * <p> If the {@code name} is "{@code <init>};"or "{@code <clinit>}" a
1.1557 + * {@code NoSuchMethodException} is raised. Otherwise, the method to
1.1558 + * be reflected is determined by the algorithm that follows. Let C be the
1.1559 + * class represented by this object:
1.1560 + * <OL>
1.1561 + * <LI> C is searched for any <I>matching methods</I>. If no matching
1.1562 + * method is found, the algorithm of step 1 is invoked recursively on
1.1563 + * the superclass of C.</LI>
1.1564 + * <LI> If no method was found in step 1 above, the superinterfaces of C
1.1565 + * are searched for a matching method. If any such method is found, it
1.1566 + * is reflected.</LI>
1.1567 + * </OL>
1.1568 + *
1.1569 + * To find a matching method in a class C: If C declares exactly one
1.1570 + * public method with the specified name and exactly the same formal
1.1571 + * parameter types, that is the method reflected. If more than one such
1.1572 + * method is found in C, and one of these methods has a return type that is
1.1573 + * more specific than any of the others, that method is reflected;
1.1574 + * otherwise one of the methods is chosen arbitrarily.
1.1575 + *
1.1576 + * <p>Note that there may be more than one matching method in a
1.1577 + * class because while the Java language forbids a class to
1.1578 + * declare multiple methods with the same signature but different
1.1579 + * return types, the Java virtual machine does not. This
1.1580 + * increased flexibility in the virtual machine can be used to
1.1581 + * implement various language features. For example, covariant
1.1582 + * returns can be implemented with {@linkplain
1.1583 + * java.lang.reflect.Method#isBridge bridge methods}; the bridge
1.1584 + * method and the method being overridden would have the same
1.1585 + * signature but different return types.
1.1586 + *
1.1587 + * <p> See <em>The Java Language Specification</em>, sections 8.2 and 8.4.
1.1588 + *
1.1589 + * @param name the name of the method
1.1590 + * @param parameterTypes the list of parameters
1.1591 + * @return the {@code Method} object that matches the specified
1.1592 + * {@code name} and {@code parameterTypes}
1.1593 + * @exception NoSuchMethodException if a matching method is not found
1.1594 + * or if the name is "<init>"or "<clinit>".
1.1595 + * @exception NullPointerException if {@code name} is {@code null}
1.1596 + * @exception SecurityException
1.1597 + * If a security manager, <i>s</i>, is present and any of the
1.1598 + * following conditions is met:
1.1599 + *
1.1600 + * <ul>
1.1601 + *
1.1602 + * <li> invocation of
1.1603 + * {@link SecurityManager#checkMemberAccess
1.1604 + * s.checkMemberAccess(this, Member.PUBLIC)} denies
1.1605 + * access to the method
1.1606 + *
1.1607 + * <li> the caller's class loader is not the same as or an
1.1608 + * ancestor of the class loader for the current class and
1.1609 + * invocation of {@link SecurityManager#checkPackageAccess
1.1610 + * s.checkPackageAccess()} denies access to the package
1.1611 + * of this class
1.1612 + *
1.1613 + * </ul>
1.1614 + *
1.1615 + * @since JDK1.1
1.1616 + */
1.1617 + public Method getMethod(String name, Class<?>... parameterTypes)
1.1618 + throws NoSuchMethodException, SecurityException {
1.1619 + // be very careful not to change the stack depth of this
1.1620 + // checkMemberAccess call for security reasons
1.1621 + // see java.lang.SecurityManager.checkMemberAccess
1.1622 + checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
1.1623 + Method method = getMethod0(name, parameterTypes);
1.1624 + if (method == null) {
1.1625 + throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
1.1626 + }
1.1627 + return method;
1.1628 + }
1.1629 +
1.1630 +
1.1631 + /**
1.1632 + * Returns a {@code Constructor} object that reflects the specified
1.1633 + * public constructor of the class represented by this {@code Class}
1.1634 + * object. The {@code parameterTypes} parameter is an array of
1.1635 + * {@code Class} objects that identify the constructor's formal
1.1636 + * parameter types, in declared order.
1.1637 + *
1.1638 + * If this {@code Class} object represents an inner class
1.1639 + * declared in a non-static context, the formal parameter types
1.1640 + * include the explicit enclosing instance as the first parameter.
1.1641 + *
1.1642 + * <p> The constructor to reflect is the public constructor of the class
1.1643 + * represented by this {@code Class} object whose formal parameter
1.1644 + * types match those specified by {@code parameterTypes}.
1.1645 + *
1.1646 + * @param parameterTypes the parameter array
1.1647 + * @return the {@code Constructor} object of the public constructor that
1.1648 + * matches the specified {@code parameterTypes}
1.1649 + * @exception NoSuchMethodException if a matching method is not found.
1.1650 + * @exception SecurityException
1.1651 + * If a security manager, <i>s</i>, is present and any of the
1.1652 + * following conditions is met:
1.1653 + *
1.1654 + * <ul>
1.1655 + *
1.1656 + * <li> invocation of
1.1657 + * {@link SecurityManager#checkMemberAccess
1.1658 + * s.checkMemberAccess(this, Member.PUBLIC)} denies
1.1659 + * access to the constructor
1.1660 + *
1.1661 + * <li> the caller's class loader is not the same as or an
1.1662 + * ancestor of the class loader for the current class and
1.1663 + * invocation of {@link SecurityManager#checkPackageAccess
1.1664 + * s.checkPackageAccess()} denies access to the package
1.1665 + * of this class
1.1666 + *
1.1667 + * </ul>
1.1668 + *
1.1669 + * @since JDK1.1
1.1670 + */
1.1671 + public Constructor<T> getConstructor(Class<?>... parameterTypes)
1.1672 + throws NoSuchMethodException, SecurityException {
1.1673 + // be very careful not to change the stack depth of this
1.1674 + // checkMemberAccess call for security reasons
1.1675 + // see java.lang.SecurityManager.checkMemberAccess
1.1676 + checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
1.1677 + return getConstructor0(parameterTypes, Member.PUBLIC);
1.1678 + }
1.1679 +
1.1680 +
1.1681 + /**
1.1682 + * Returns an array of {@code Class} objects reflecting all the
1.1683 + * classes and interfaces declared as members of the class represented by
1.1684 + * this {@code Class} object. This includes public, protected, default
1.1685 + * (package) access, and private classes and interfaces declared by the
1.1686 + * class, but excludes inherited classes and interfaces. This method
1.1687 + * returns an array of length 0 if the class declares no classes or
1.1688 + * interfaces as members, or if this {@code Class} object represents a
1.1689 + * primitive type, an array class, or void.
1.1690 + *
1.1691 + * @return the array of {@code Class} objects representing all the
1.1692 + * declared members of this class
1.1693 + * @exception SecurityException
1.1694 + * If a security manager, <i>s</i>, is present and any of the
1.1695 + * following conditions is met:
1.1696 + *
1.1697 + * <ul>
1.1698 + *
1.1699 + * <li> invocation of
1.1700 + * {@link SecurityManager#checkMemberAccess
1.1701 + * s.checkMemberAccess(this, Member.DECLARED)} denies
1.1702 + * access to the declared classes within this class
1.1703 + *
1.1704 + * <li> the caller's class loader is not the same as or an
1.1705 + * ancestor of the class loader for the current class and
1.1706 + * invocation of {@link SecurityManager#checkPackageAccess
1.1707 + * s.checkPackageAccess()} denies access to the package
1.1708 + * of this class
1.1709 + *
1.1710 + * </ul>
1.1711 + *
1.1712 + * @since JDK1.1
1.1713 + */
1.1714 + public Class<?>[] getDeclaredClasses() throws SecurityException {
1.1715 + // be very careful not to change the stack depth of this
1.1716 + // checkMemberAccess call for security reasons
1.1717 + // see java.lang.SecurityManager.checkMemberAccess
1.1718 + checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
1.1719 + return getDeclaredClasses0();
1.1720 + }
1.1721 +
1.1722 +
1.1723 + /**
1.1724 + * Returns an array of {@code Field} objects reflecting all the fields
1.1725 + * declared by the class or interface represented by this
1.1726 + * {@code Class} object. This includes public, protected, default
1.1727 + * (package) access, and private fields, but excludes inherited fields.
1.1728 + * The elements in the array returned are not sorted and are not in any
1.1729 + * particular order. This method returns an array of length 0 if the class
1.1730 + * or interface declares no fields, or if this {@code Class} object
1.1731 + * represents a primitive type, an array class, or void.
1.1732 + *
1.1733 + * <p> See <em>The Java Language Specification</em>, sections 8.2 and 8.3.
1.1734 + *
1.1735 + * @return the array of {@code Field} objects representing all the
1.1736 + * declared fields of this class
1.1737 + * @exception SecurityException
1.1738 + * If a security manager, <i>s</i>, is present and any of the
1.1739 + * following conditions is met:
1.1740 + *
1.1741 + * <ul>
1.1742 + *
1.1743 + * <li> invocation of
1.1744 + * {@link SecurityManager#checkMemberAccess
1.1745 + * s.checkMemberAccess(this, Member.DECLARED)} denies
1.1746 + * access to the declared fields within this class
1.1747 + *
1.1748 + * <li> the caller's class loader is not the same as or an
1.1749 + * ancestor of the class loader for the current class and
1.1750 + * invocation of {@link SecurityManager#checkPackageAccess
1.1751 + * s.checkPackageAccess()} denies access to the package
1.1752 + * of this class
1.1753 + *
1.1754 + * </ul>
1.1755 + *
1.1756 + * @since JDK1.1
1.1757 + */
1.1758 + public Field[] getDeclaredFields() throws SecurityException {
1.1759 + // be very careful not to change the stack depth of this
1.1760 + // checkMemberAccess call for security reasons
1.1761 + // see java.lang.SecurityManager.checkMemberAccess
1.1762 + checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
1.1763 + return copyFields(privateGetDeclaredFields(false));
1.1764 + }
1.1765 +
1.1766 +
1.1767 + /**
1.1768 + * Returns an array of {@code Method} objects reflecting all the
1.1769 + * methods declared by the class or interface represented by this
1.1770 + * {@code Class} object. This includes public, protected, default
1.1771 + * (package) access, and private methods, but excludes inherited methods.
1.1772 + * The elements in the array returned are not sorted and are not in any
1.1773 + * particular order. This method returns an array of length 0 if the class
1.1774 + * or interface declares no methods, or if this {@code Class} object
1.1775 + * represents a primitive type, an array class, or void. The class
1.1776 + * initialization method {@code <clinit>} is not included in the
1.1777 + * returned array. If the class declares multiple public member methods
1.1778 + * with the same parameter types, they are all included in the returned
1.1779 + * array.
1.1780 + *
1.1781 + * <p> See <em>The Java Language Specification</em>, section 8.2.
1.1782 + *
1.1783 + * @return the array of {@code Method} objects representing all the
1.1784 + * declared methods of this class
1.1785 + * @exception SecurityException
1.1786 + * If a security manager, <i>s</i>, is present and any of the
1.1787 + * following conditions is met:
1.1788 + *
1.1789 + * <ul>
1.1790 + *
1.1791 + * <li> invocation of
1.1792 + * {@link SecurityManager#checkMemberAccess
1.1793 + * s.checkMemberAccess(this, Member.DECLARED)} denies
1.1794 + * access to the declared methods within this class
1.1795 + *
1.1796 + * <li> the caller's class loader is not the same as or an
1.1797 + * ancestor of the class loader for the current class and
1.1798 + * invocation of {@link SecurityManager#checkPackageAccess
1.1799 + * s.checkPackageAccess()} denies access to the package
1.1800 + * of this class
1.1801 + *
1.1802 + * </ul>
1.1803 + *
1.1804 + * @since JDK1.1
1.1805 + */
1.1806 + public Method[] getDeclaredMethods() throws SecurityException {
1.1807 + // be very careful not to change the stack depth of this
1.1808 + // checkMemberAccess call for security reasons
1.1809 + // see java.lang.SecurityManager.checkMemberAccess
1.1810 + checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
1.1811 + return copyMethods(privateGetDeclaredMethods(false));
1.1812 + }
1.1813 +
1.1814 +
1.1815 + /**
1.1816 + * Returns an array of {@code Constructor} objects reflecting all the
1.1817 + * constructors declared by the class represented by this
1.1818 + * {@code Class} object. These are public, protected, default
1.1819 + * (package) access, and private constructors. The elements in the array
1.1820 + * returned are not sorted and are not in any particular order. If the
1.1821 + * class has a default constructor, it is included in the returned array.
1.1822 + * This method returns an array of length 0 if this {@code Class}
1.1823 + * object represents an interface, a primitive type, an array class, or
1.1824 + * void.
1.1825 + *
1.1826 + * <p> See <em>The Java Language Specification</em>, section 8.2.
1.1827 + *
1.1828 + * @return the array of {@code Constructor} objects representing all the
1.1829 + * declared constructors of this class
1.1830 + * @exception SecurityException
1.1831 + * If a security manager, <i>s</i>, is present and any of the
1.1832 + * following conditions is met:
1.1833 + *
1.1834 + * <ul>
1.1835 + *
1.1836 + * <li> invocation of
1.1837 + * {@link SecurityManager#checkMemberAccess
1.1838 + * s.checkMemberAccess(this, Member.DECLARED)} denies
1.1839 + * access to the declared constructors within this class
1.1840 + *
1.1841 + * <li> the caller's class loader is not the same as or an
1.1842 + * ancestor of the class loader for the current class and
1.1843 + * invocation of {@link SecurityManager#checkPackageAccess
1.1844 + * s.checkPackageAccess()} denies access to the package
1.1845 + * of this class
1.1846 + *
1.1847 + * </ul>
1.1848 + *
1.1849 + * @since JDK1.1
1.1850 + */
1.1851 + public Constructor<?>[] getDeclaredConstructors() throws SecurityException {
1.1852 + // be very careful not to change the stack depth of this
1.1853 + // checkMemberAccess call for security reasons
1.1854 + // see java.lang.SecurityManager.checkMemberAccess
1.1855 + checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
1.1856 + return copyConstructors(privateGetDeclaredConstructors(false));
1.1857 + }
1.1858 +
1.1859 +
1.1860 + /**
1.1861 + * Returns a {@code Field} object that reflects the specified declared
1.1862 + * field of the class or interface represented by this {@code Class}
1.1863 + * object. The {@code name} parameter is a {@code String} that
1.1864 + * specifies the simple name of the desired field. Note that this method
1.1865 + * will not reflect the {@code length} field of an array class.
1.1866 + *
1.1867 + * @param name the name of the field
1.1868 + * @return the {@code Field} object for the specified field in this
1.1869 + * class
1.1870 + * @exception NoSuchFieldException if a field with the specified name is
1.1871 + * not found.
1.1872 + * @exception NullPointerException if {@code name} is {@code null}
1.1873 + * @exception SecurityException
1.1874 + * If a security manager, <i>s</i>, is present and any of the
1.1875 + * following conditions is met:
1.1876 + *
1.1877 + * <ul>
1.1878 + *
1.1879 + * <li> invocation of
1.1880 + * {@link SecurityManager#checkMemberAccess
1.1881 + * s.checkMemberAccess(this, Member.DECLARED)} denies
1.1882 + * access to the declared field
1.1883 + *
1.1884 + * <li> the caller's class loader is not the same as or an
1.1885 + * ancestor of the class loader for the current class and
1.1886 + * invocation of {@link SecurityManager#checkPackageAccess
1.1887 + * s.checkPackageAccess()} denies access to the package
1.1888 + * of this class
1.1889 + *
1.1890 + * </ul>
1.1891 + *
1.1892 + * @since JDK1.1
1.1893 + */
1.1894 + public Field getDeclaredField(String name)
1.1895 + throws NoSuchFieldException, SecurityException {
1.1896 + // be very careful not to change the stack depth of this
1.1897 + // checkMemberAccess call for security reasons
1.1898 + // see java.lang.SecurityManager.checkMemberAccess
1.1899 + checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
1.1900 + Field field = searchFields(privateGetDeclaredFields(false), name);
1.1901 + if (field == null) {
1.1902 + throw new NoSuchFieldException(name);
1.1903 + }
1.1904 + return field;
1.1905 + }
1.1906 +
1.1907 +
1.1908 + /**
1.1909 + * Returns a {@code Method} object that reflects the specified
1.1910 + * declared method of the class or interface represented by this
1.1911 + * {@code Class} object. The {@code name} parameter is a
1.1912 + * {@code String} that specifies the simple name of the desired
1.1913 + * method, and the {@code parameterTypes} parameter is an array of
1.1914 + * {@code Class} objects that identify the method's formal parameter
1.1915 + * types, in declared order. If more than one method with the same
1.1916 + * parameter types is declared in a class, and one of these methods has a
1.1917 + * return type that is more specific than any of the others, that method is
1.1918 + * returned; otherwise one of the methods is chosen arbitrarily. If the
1.1919 + * name is "<init>"or "<clinit>" a {@code NoSuchMethodException}
1.1920 + * is raised.
1.1921 + *
1.1922 + * @param name the name of the method
1.1923 + * @param parameterTypes the parameter array
1.1924 + * @return the {@code Method} object for the method of this class
1.1925 + * matching the specified name and parameters
1.1926 + * @exception NoSuchMethodException if a matching method is not found.
1.1927 + * @exception NullPointerException if {@code name} is {@code null}
1.1928 + * @exception SecurityException
1.1929 + * If a security manager, <i>s</i>, is present and any of the
1.1930 + * following conditions is met:
1.1931 + *
1.1932 + * <ul>
1.1933 + *
1.1934 + * <li> invocation of
1.1935 + * {@link SecurityManager#checkMemberAccess
1.1936 + * s.checkMemberAccess(this, Member.DECLARED)} denies
1.1937 + * access to the declared method
1.1938 + *
1.1939 + * <li> the caller's class loader is not the same as or an
1.1940 + * ancestor of the class loader for the current class and
1.1941 + * invocation of {@link SecurityManager#checkPackageAccess
1.1942 + * s.checkPackageAccess()} denies access to the package
1.1943 + * of this class
1.1944 + *
1.1945 + * </ul>
1.1946 + *
1.1947 + * @since JDK1.1
1.1948 + */
1.1949 + public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
1.1950 + throws NoSuchMethodException, SecurityException {
1.1951 + // be very careful not to change the stack depth of this
1.1952 + // checkMemberAccess call for security reasons
1.1953 + // see java.lang.SecurityManager.checkMemberAccess
1.1954 + checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
1.1955 + Method method = searchMethods(privateGetDeclaredMethods(false), name, parameterTypes);
1.1956 + if (method == null) {
1.1957 + throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
1.1958 + }
1.1959 + return method;
1.1960 + }
1.1961 +
1.1962 +
1.1963 + /**
1.1964 + * Returns a {@code Constructor} object that reflects the specified
1.1965 + * constructor of the class or interface represented by this
1.1966 + * {@code Class} object. The {@code parameterTypes} parameter is
1.1967 + * an array of {@code Class} objects that identify the constructor's
1.1968 + * formal parameter types, in declared order.
1.1969 + *
1.1970 + * If this {@code Class} object represents an inner class
1.1971 + * declared in a non-static context, the formal parameter types
1.1972 + * include the explicit enclosing instance as the first parameter.
1.1973 + *
1.1974 + * @param parameterTypes the parameter array
1.1975 + * @return The {@code Constructor} object for the constructor with the
1.1976 + * specified parameter list
1.1977 + * @exception NoSuchMethodException if a matching method is not found.
1.1978 + * @exception SecurityException
1.1979 + * If a security manager, <i>s</i>, is present and any of the
1.1980 + * following conditions is met:
1.1981 + *
1.1982 + * <ul>
1.1983 + *
1.1984 + * <li> invocation of
1.1985 + * {@link SecurityManager#checkMemberAccess
1.1986 + * s.checkMemberAccess(this, Member.DECLARED)} denies
1.1987 + * access to the declared constructor
1.1988 + *
1.1989 + * <li> the caller's class loader is not the same as or an
1.1990 + * ancestor of the class loader for the current class and
1.1991 + * invocation of {@link SecurityManager#checkPackageAccess
1.1992 + * s.checkPackageAccess()} denies access to the package
1.1993 + * of this class
1.1994 + *
1.1995 + * </ul>
1.1996 + *
1.1997 + * @since JDK1.1
1.1998 + */
1.1999 + public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
1.2000 + throws NoSuchMethodException, SecurityException {
1.2001 + // be very careful not to change the stack depth of this
1.2002 + // checkMemberAccess call for security reasons
1.2003 + // see java.lang.SecurityManager.checkMemberAccess
1.2004 + checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
1.2005 + return getConstructor0(parameterTypes, Member.DECLARED);
1.2006 + }
1.2007 +
1.2008 + /**
1.2009 + * Finds a resource with a given name. The rules for searching resources
1.2010 + * associated with a given class are implemented by the defining
1.2011 + * {@linkplain ClassLoader class loader} of the class. This method
1.2012 + * delegates to this object's class loader. If this object was loaded by
1.2013 + * the bootstrap class loader, the method delegates to {@link
1.2014 + * ClassLoader#getSystemResourceAsStream}.
1.2015 + *
1.2016 + * <p> Before delegation, an absolute resource name is constructed from the
1.2017 + * given resource name using this algorithm:
1.2018 + *
1.2019 + * <ul>
1.2020 + *
1.2021 + * <li> If the {@code name} begins with a {@code '/'}
1.2022 + * (<tt>'\u002f'</tt>), then the absolute name of the resource is the
1.2023 + * portion of the {@code name} following the {@code '/'}.
1.2024 + *
1.2025 + * <li> Otherwise, the absolute name is of the following form:
1.2026 + *
1.2027 + * <blockquote>
1.2028 + * {@code modified_package_name/name}
1.2029 + * </blockquote>
1.2030 + *
1.2031 + * <p> Where the {@code modified_package_name} is the package name of this
1.2032 + * object with {@code '/'} substituted for {@code '.'}
1.2033 + * (<tt>'\u002e'</tt>).
1.2034 + *
1.2035 + * </ul>
1.2036 + *
1.2037 + * @param name name of the desired resource
1.2038 + * @return A {@link java.io.InputStream} object or {@code null} if
1.2039 + * no resource with this name is found
1.2040 + * @throws NullPointerException If {@code name} is {@code null}
1.2041 + * @since JDK1.1
1.2042 + */
1.2043 + public InputStream getResourceAsStream(String name) {
1.2044 + name = resolveName(name);
1.2045 + ClassLoader cl = getClassLoader0();
1.2046 + if (cl==null) {
1.2047 + // A system class.
1.2048 + return ClassLoader.getSystemResourceAsStream(name);
1.2049 + }
1.2050 + return cl.getResourceAsStream(name);
1.2051 + }
1.2052 +
1.2053 + /**
1.2054 + * Finds a resource with a given name. The rules for searching resources
1.2055 + * associated with a given class are implemented by the defining
1.2056 + * {@linkplain ClassLoader class loader} of the class. This method
1.2057 + * delegates to this object's class loader. If this object was loaded by
1.2058 + * the bootstrap class loader, the method delegates to {@link
1.2059 + * ClassLoader#getSystemResource}.
1.2060 + *
1.2061 + * <p> Before delegation, an absolute resource name is constructed from the
1.2062 + * given resource name using this algorithm:
1.2063 + *
1.2064 + * <ul>
1.2065 + *
1.2066 + * <li> If the {@code name} begins with a {@code '/'}
1.2067 + * (<tt>'\u002f'</tt>), then the absolute name of the resource is the
1.2068 + * portion of the {@code name} following the {@code '/'}.
1.2069 + *
1.2070 + * <li> Otherwise, the absolute name is of the following form:
1.2071 + *
1.2072 + * <blockquote>
1.2073 + * {@code modified_package_name/name}
1.2074 + * </blockquote>
1.2075 + *
1.2076 + * <p> Where the {@code modified_package_name} is the package name of this
1.2077 + * object with {@code '/'} substituted for {@code '.'}
1.2078 + * (<tt>'\u002e'</tt>).
1.2079 + *
1.2080 + * </ul>
1.2081 + *
1.2082 + * @param name name of the desired resource
1.2083 + * @return A {@link java.net.URL} object or {@code null} if no
1.2084 + * resource with this name is found
1.2085 + * @since JDK1.1
1.2086 + */
1.2087 + public java.net.URL getResource(String name) {
1.2088 + name = resolveName(name);
1.2089 + ClassLoader cl = getClassLoader0();
1.2090 + if (cl==null) {
1.2091 + // A system class.
1.2092 + return ClassLoader.getSystemResource(name);
1.2093 + }
1.2094 + return cl.getResource(name);
1.2095 + }
1.2096 +
1.2097 +
1.2098 +
1.2099 + /** protection domain returned when the internal domain is null */
1.2100 + private static java.security.ProtectionDomain allPermDomain;
1.2101 +
1.2102 +
1.2103 + /**
1.2104 + * Returns the {@code ProtectionDomain} of this class. If there is a
1.2105 + * security manager installed, this method first calls the security
1.2106 + * manager's {@code checkPermission} method with a
1.2107 + * {@code RuntimePermission("getProtectionDomain")} permission to
1.2108 + * ensure it's ok to get the
1.2109 + * {@code ProtectionDomain}.
1.2110 + *
1.2111 + * @return the ProtectionDomain of this class
1.2112 + *
1.2113 + * @throws SecurityException
1.2114 + * if a security manager exists and its
1.2115 + * {@code checkPermission} method doesn't allow
1.2116 + * getting the ProtectionDomain.
1.2117 + *
1.2118 + * @see java.security.ProtectionDomain
1.2119 + * @see SecurityManager#checkPermission
1.2120 + * @see java.lang.RuntimePermission
1.2121 + * @since 1.2
1.2122 + */
1.2123 + public java.security.ProtectionDomain getProtectionDomain() {
1.2124 + SecurityManager sm = System.getSecurityManager();
1.2125 + if (sm != null) {
1.2126 + sm.checkPermission(SecurityConstants.GET_PD_PERMISSION);
1.2127 + }
1.2128 + java.security.ProtectionDomain pd = getProtectionDomain0();
1.2129 + if (pd == null) {
1.2130 + if (allPermDomain == null) {
1.2131 + java.security.Permissions perms =
1.2132 + new java.security.Permissions();
1.2133 + perms.add(SecurityConstants.ALL_PERMISSION);
1.2134 + allPermDomain =
1.2135 + new java.security.ProtectionDomain(null, perms);
1.2136 + }
1.2137 + pd = allPermDomain;
1.2138 + }
1.2139 + return pd;
1.2140 + }
1.2141 +
1.2142 +
1.2143 + /**
1.2144 + * Returns the ProtectionDomain of this class.
1.2145 + */
1.2146 + private native java.security.ProtectionDomain getProtectionDomain0();
1.2147 +
1.2148 +
1.2149 + /**
1.2150 + * Set the ProtectionDomain for this class. Called by
1.2151 + * ClassLoader.defineClass.
1.2152 + */
1.2153 + native void setProtectionDomain0(java.security.ProtectionDomain pd);
1.2154 +
1.2155 +
1.2156 + /*
1.2157 + * Return the Virtual Machine's Class object for the named
1.2158 + * primitive type.
1.2159 + */
1.2160 + static native Class getPrimitiveClass(String name);
1.2161 +
1.2162 +
1.2163 + /*
1.2164 + * Check if client is allowed to access members. If access is denied,
1.2165 + * throw a SecurityException.
1.2166 + *
1.2167 + * Be very careful not to change the stack depth of this checkMemberAccess
1.2168 + * call for security reasons.
1.2169 + * See java.lang.SecurityManager.checkMemberAccess.
1.2170 + *
1.2171 + * <p> Default policy: allow all clients access with normal Java access
1.2172 + * control.
1.2173 + */
1.2174 + private void checkMemberAccess(int which, ClassLoader ccl) {
1.2175 + SecurityManager s = System.getSecurityManager();
1.2176 + if (s != null) {
1.2177 + s.checkMemberAccess(this, which);
1.2178 + ClassLoader cl = getClassLoader0();
1.2179 + if ((ccl != null) && (ccl != cl) &&
1.2180 + ((cl == null) || !cl.isAncestor(ccl))) {
1.2181 + String name = this.getName();
1.2182 + int i = name.lastIndexOf('.');
1.2183 + if (i != -1) {
1.2184 + s.checkPackageAccess(name.substring(0, i));
1.2185 + }
1.2186 + }
1.2187 + }
1.2188 + }
1.2189 +
1.2190 + /**
1.2191 + * Add a package name prefix if the name is not absolute Remove leading "/"
1.2192 + * if name is absolute
1.2193 + */
1.2194 + private String resolveName(String name) {
1.2195 + if (name == null) {
1.2196 + return name;
1.2197 + }
1.2198 + if (!name.startsWith("/")) {
1.2199 + Class<?> c = this;
1.2200 + while (c.isArray()) {
1.2201 + c = c.getComponentType();
1.2202 + }
1.2203 + String baseName = c.getName();
1.2204 + int index = baseName.lastIndexOf('.');
1.2205 + if (index != -1) {
1.2206 + name = baseName.substring(0, index).replace('.', '/')
1.2207 + +"/"+name;
1.2208 + }
1.2209 + } else {
1.2210 + name = name.substring(1);
1.2211 + }
1.2212 + return name;
1.2213 + }
1.2214 +
1.2215 + /**
1.2216 + * Reflection support.
1.2217 + */
1.2218 +
1.2219 + // Caches for certain reflective results
1.2220 + private static boolean useCaches = true;
1.2221 + private volatile transient SoftReference<Field[]> declaredFields;
1.2222 + private volatile transient SoftReference<Field[]> publicFields;
1.2223 + private volatile transient SoftReference<Method[]> declaredMethods;
1.2224 + private volatile transient SoftReference<Method[]> publicMethods;
1.2225 + private volatile transient SoftReference<Constructor<T>[]> declaredConstructors;
1.2226 + private volatile transient SoftReference<Constructor<T>[]> publicConstructors;
1.2227 + // Intermediate results for getFields and getMethods
1.2228 + private volatile transient SoftReference<Field[]> declaredPublicFields;
1.2229 + private volatile transient SoftReference<Method[]> declaredPublicMethods;
1.2230 +
1.2231 + // Incremented by the VM on each call to JVM TI RedefineClasses()
1.2232 + // that redefines this class or a superclass.
1.2233 + private volatile transient int classRedefinedCount = 0;
1.2234 +
1.2235 + // Value of classRedefinedCount when we last cleared the cached values
1.2236 + // that are sensitive to class redefinition.
1.2237 + private volatile transient int lastRedefinedCount = 0;
1.2238 +
1.2239 + // Clears cached values that might possibly have been obsoleted by
1.2240 + // a class redefinition.
1.2241 + private void clearCachesOnClassRedefinition() {
1.2242 + if (lastRedefinedCount != classRedefinedCount) {
1.2243 + declaredFields = publicFields = declaredPublicFields = null;
1.2244 + declaredMethods = publicMethods = declaredPublicMethods = null;
1.2245 + declaredConstructors = publicConstructors = null;
1.2246 + annotations = declaredAnnotations = null;
1.2247 +
1.2248 + // Use of "volatile" (and synchronization by caller in the case
1.2249 + // of annotations) ensures that no thread sees the update to
1.2250 + // lastRedefinedCount before seeing the caches cleared.
1.2251 + // We do not guard against brief windows during which multiple
1.2252 + // threads might redundantly work to fill an empty cache.
1.2253 + lastRedefinedCount = classRedefinedCount;
1.2254 + }
1.2255 + }
1.2256 +
1.2257 + // Generic signature handling
1.2258 + private native String getGenericSignature();
1.2259 +
1.2260 + // Generic info repository; lazily initialized
1.2261 + private transient ClassRepository genericInfo;
1.2262 +
1.2263 + // accessor for factory
1.2264 + private GenericsFactory getFactory() {
1.2265 + // create scope and factory
1.2266 + return CoreReflectionFactory.make(this, ClassScope.make(this));
1.2267 + }
1.2268 +
1.2269 + // accessor for generic info repository
1.2270 + private ClassRepository getGenericInfo() {
1.2271 + // lazily initialize repository if necessary
1.2272 + if (genericInfo == null) {
1.2273 + // create and cache generic info repository
1.2274 + genericInfo = ClassRepository.make(getGenericSignature(),
1.2275 + getFactory());
1.2276 + }
1.2277 + return genericInfo; //return cached repository
1.2278 + }
1.2279 +
1.2280 + // Annotations handling
1.2281 + private native byte[] getRawAnnotations();
1.2282 +
1.2283 + native ConstantPool getConstantPool();
1.2284 +
1.2285 + //
1.2286 + //
1.2287 + // java.lang.reflect.Field handling
1.2288 + //
1.2289 + //
1.2290 +
1.2291 + // Returns an array of "root" fields. These Field objects must NOT
1.2292 + // be propagated to the outside world, but must instead be copied
1.2293 + // via ReflectionFactory.copyField.
1.2294 + private Field[] privateGetDeclaredFields(boolean publicOnly) {
1.2295 + checkInitted();
1.2296 + Field[] res = null;
1.2297 + if (useCaches) {
1.2298 + clearCachesOnClassRedefinition();
1.2299 + if (publicOnly) {
1.2300 + if (declaredPublicFields != null) {
1.2301 + res = declaredPublicFields.get();
1.2302 + }
1.2303 + } else {
1.2304 + if (declaredFields != null) {
1.2305 + res = declaredFields.get();
1.2306 + }
1.2307 + }
1.2308 + if (res != null) return res;
1.2309 + }
1.2310 + // No cached value available; request value from VM
1.2311 + res = Reflection.filterFields(this, getDeclaredFields0(publicOnly));
1.2312 + if (useCaches) {
1.2313 + if (publicOnly) {
1.2314 + declaredPublicFields = new SoftReference<>(res);
1.2315 + } else {
1.2316 + declaredFields = new SoftReference<>(res);
1.2317 + }
1.2318 + }
1.2319 + return res;
1.2320 + }
1.2321 +
1.2322 + // Returns an array of "root" fields. These Field objects must NOT
1.2323 + // be propagated to the outside world, but must instead be copied
1.2324 + // via ReflectionFactory.copyField.
1.2325 + private Field[] privateGetPublicFields(Set<Class<?>> traversedInterfaces) {
1.2326 + checkInitted();
1.2327 + Field[] res = null;
1.2328 + if (useCaches) {
1.2329 + clearCachesOnClassRedefinition();
1.2330 + if (publicFields != null) {
1.2331 + res = publicFields.get();
1.2332 + }
1.2333 + if (res != null) return res;
1.2334 + }
1.2335 +
1.2336 + // No cached value available; compute value recursively.
1.2337 + // Traverse in correct order for getField().
1.2338 + List<Field> fields = new ArrayList<>();
1.2339 + if (traversedInterfaces == null) {
1.2340 + traversedInterfaces = new HashSet<>();
1.2341 + }
1.2342 +
1.2343 + // Local fields
1.2344 + Field[] tmp = privateGetDeclaredFields(true);
1.2345 + addAll(fields, tmp);
1.2346 +
1.2347 + // Direct superinterfaces, recursively
1.2348 + for (Class<?> c : getInterfaces()) {
1.2349 + if (!traversedInterfaces.contains(c)) {
1.2350 + traversedInterfaces.add(c);
1.2351 + addAll(fields, c.privateGetPublicFields(traversedInterfaces));
1.2352 + }
1.2353 + }
1.2354 +
1.2355 + // Direct superclass, recursively
1.2356 + if (!isInterface()) {
1.2357 + Class<?> c = getSuperclass();
1.2358 + if (c != null) {
1.2359 + addAll(fields, c.privateGetPublicFields(traversedInterfaces));
1.2360 + }
1.2361 + }
1.2362 +
1.2363 + res = new Field[fields.size()];
1.2364 + fields.toArray(res);
1.2365 + if (useCaches) {
1.2366 + publicFields = new SoftReference<>(res);
1.2367 + }
1.2368 + return res;
1.2369 + }
1.2370 +
1.2371 + private static void addAll(Collection<Field> c, Field[] o) {
1.2372 + for (int i = 0; i < o.length; i++) {
1.2373 + c.add(o[i]);
1.2374 + }
1.2375 + }
1.2376 +
1.2377 +
1.2378 + //
1.2379 + //
1.2380 + // java.lang.reflect.Constructor handling
1.2381 + //
1.2382 + //
1.2383 +
1.2384 + // Returns an array of "root" constructors. These Constructor
1.2385 + // objects must NOT be propagated to the outside world, but must
1.2386 + // instead be copied via ReflectionFactory.copyConstructor.
1.2387 + private Constructor<T>[] privateGetDeclaredConstructors(boolean publicOnly) {
1.2388 + checkInitted();
1.2389 + Constructor<T>[] res = null;
1.2390 + if (useCaches) {
1.2391 + clearCachesOnClassRedefinition();
1.2392 + if (publicOnly) {
1.2393 + if (publicConstructors != null) {
1.2394 + res = publicConstructors.get();
1.2395 + }
1.2396 + } else {
1.2397 + if (declaredConstructors != null) {
1.2398 + res = declaredConstructors.get();
1.2399 + }
1.2400 + }
1.2401 + if (res != null) return res;
1.2402 + }
1.2403 + // No cached value available; request value from VM
1.2404 + if (isInterface()) {
1.2405 + res = new Constructor[0];
1.2406 + } else {
1.2407 + res = getDeclaredConstructors0(publicOnly);
1.2408 + }
1.2409 + if (useCaches) {
1.2410 + if (publicOnly) {
1.2411 + publicConstructors = new SoftReference<>(res);
1.2412 + } else {
1.2413 + declaredConstructors = new SoftReference<>(res);
1.2414 + }
1.2415 + }
1.2416 + return res;
1.2417 + }
1.2418 +
1.2419 + //
1.2420 + //
1.2421 + // java.lang.reflect.Method handling
1.2422 + //
1.2423 + //
1.2424 +
1.2425 + // Returns an array of "root" methods. These Method objects must NOT
1.2426 + // be propagated to the outside world, but must instead be copied
1.2427 + // via ReflectionFactory.copyMethod.
1.2428 + private Method[] privateGetDeclaredMethods(boolean publicOnly) {
1.2429 + checkInitted();
1.2430 + Method[] res = null;
1.2431 + if (useCaches) {
1.2432 + clearCachesOnClassRedefinition();
1.2433 + if (publicOnly) {
1.2434 + if (declaredPublicMethods != null) {
1.2435 + res = declaredPublicMethods.get();
1.2436 + }
1.2437 + } else {
1.2438 + if (declaredMethods != null) {
1.2439 + res = declaredMethods.get();
1.2440 + }
1.2441 + }
1.2442 + if (res != null) return res;
1.2443 + }
1.2444 + // No cached value available; request value from VM
1.2445 + res = Reflection.filterMethods(this, getDeclaredMethods0(publicOnly));
1.2446 + if (useCaches) {
1.2447 + if (publicOnly) {
1.2448 + declaredPublicMethods = new SoftReference<>(res);
1.2449 + } else {
1.2450 + declaredMethods = new SoftReference<>(res);
1.2451 + }
1.2452 + }
1.2453 + return res;
1.2454 + }
1.2455 +
1.2456 + static class MethodArray {
1.2457 + private Method[] methods;
1.2458 + private int length;
1.2459 +
1.2460 + MethodArray() {
1.2461 + methods = new Method[20];
1.2462 + length = 0;
1.2463 + }
1.2464 +
1.2465 + void add(Method m) {
1.2466 + if (length == methods.length) {
1.2467 + methods = Arrays.copyOf(methods, 2 * methods.length);
1.2468 + }
1.2469 + methods[length++] = m;
1.2470 + }
1.2471 +
1.2472 + void addAll(Method[] ma) {
1.2473 + for (int i = 0; i < ma.length; i++) {
1.2474 + add(ma[i]);
1.2475 + }
1.2476 + }
1.2477 +
1.2478 + void addAll(MethodArray ma) {
1.2479 + for (int i = 0; i < ma.length(); i++) {
1.2480 + add(ma.get(i));
1.2481 + }
1.2482 + }
1.2483 +
1.2484 + void addIfNotPresent(Method newMethod) {
1.2485 + for (int i = 0; i < length; i++) {
1.2486 + Method m = methods[i];
1.2487 + if (m == newMethod || (m != null && m.equals(newMethod))) {
1.2488 + return;
1.2489 + }
1.2490 + }
1.2491 + add(newMethod);
1.2492 + }
1.2493 +
1.2494 + void addAllIfNotPresent(MethodArray newMethods) {
1.2495 + for (int i = 0; i < newMethods.length(); i++) {
1.2496 + Method m = newMethods.get(i);
1.2497 + if (m != null) {
1.2498 + addIfNotPresent(m);
1.2499 + }
1.2500 + }
1.2501 + }
1.2502 +
1.2503 + int length() {
1.2504 + return length;
1.2505 + }
1.2506 +
1.2507 + Method get(int i) {
1.2508 + return methods[i];
1.2509 + }
1.2510 +
1.2511 + void removeByNameAndSignature(Method toRemove) {
1.2512 + for (int i = 0; i < length; i++) {
1.2513 + Method m = methods[i];
1.2514 + if (m != null &&
1.2515 + m.getReturnType() == toRemove.getReturnType() &&
1.2516 + m.getName() == toRemove.getName() &&
1.2517 + arrayContentsEq(m.getParameterTypes(),
1.2518 + toRemove.getParameterTypes())) {
1.2519 + methods[i] = null;
1.2520 + }
1.2521 + }
1.2522 + }
1.2523 +
1.2524 + void compactAndTrim() {
1.2525 + int newPos = 0;
1.2526 + // Get rid of null slots
1.2527 + for (int pos = 0; pos < length; pos++) {
1.2528 + Method m = methods[pos];
1.2529 + if (m != null) {
1.2530 + if (pos != newPos) {
1.2531 + methods[newPos] = m;
1.2532 + }
1.2533 + newPos++;
1.2534 + }
1.2535 + }
1.2536 + if (newPos != methods.length) {
1.2537 + methods = Arrays.copyOf(methods, newPos);
1.2538 + }
1.2539 + }
1.2540 +
1.2541 + Method[] getArray() {
1.2542 + return methods;
1.2543 + }
1.2544 + }
1.2545 +
1.2546 +
1.2547 + // Returns an array of "root" methods. These Method objects must NOT
1.2548 + // be propagated to the outside world, but must instead be copied
1.2549 + // via ReflectionFactory.copyMethod.
1.2550 + private Method[] privateGetPublicMethods() {
1.2551 + checkInitted();
1.2552 + Method[] res = null;
1.2553 + if (useCaches) {
1.2554 + clearCachesOnClassRedefinition();
1.2555 + if (publicMethods != null) {
1.2556 + res = publicMethods.get();
1.2557 + }
1.2558 + if (res != null) return res;
1.2559 + }
1.2560 +
1.2561 + // No cached value available; compute value recursively.
1.2562 + // Start by fetching public declared methods
1.2563 + MethodArray methods = new MethodArray();
1.2564 + {
1.2565 + Method[] tmp = privateGetDeclaredMethods(true);
1.2566 + methods.addAll(tmp);
1.2567 + }
1.2568 + // Now recur over superclass and direct superinterfaces.
1.2569 + // Go over superinterfaces first so we can more easily filter
1.2570 + // out concrete implementations inherited from superclasses at
1.2571 + // the end.
1.2572 + MethodArray inheritedMethods = new MethodArray();
1.2573 + Class<?>[] interfaces = getInterfaces();
1.2574 + for (int i = 0; i < interfaces.length; i++) {
1.2575 + inheritedMethods.addAll(interfaces[i].privateGetPublicMethods());
1.2576 + }
1.2577 + if (!isInterface()) {
1.2578 + Class<?> c = getSuperclass();
1.2579 + if (c != null) {
1.2580 + MethodArray supers = new MethodArray();
1.2581 + supers.addAll(c.privateGetPublicMethods());
1.2582 + // Filter out concrete implementations of any
1.2583 + // interface methods
1.2584 + for (int i = 0; i < supers.length(); i++) {
1.2585 + Method m = supers.get(i);
1.2586 + if (m != null && !Modifier.isAbstract(m.getModifiers())) {
1.2587 + inheritedMethods.removeByNameAndSignature(m);
1.2588 + }
1.2589 + }
1.2590 + // Insert superclass's inherited methods before
1.2591 + // superinterfaces' to satisfy getMethod's search
1.2592 + // order
1.2593 + supers.addAll(inheritedMethods);
1.2594 + inheritedMethods = supers;
1.2595 + }
1.2596 + }
1.2597 + // Filter out all local methods from inherited ones
1.2598 + for (int i = 0; i < methods.length(); i++) {
1.2599 + Method m = methods.get(i);
1.2600 + inheritedMethods.removeByNameAndSignature(m);
1.2601 + }
1.2602 + methods.addAllIfNotPresent(inheritedMethods);
1.2603 + methods.compactAndTrim();
1.2604 + res = methods.getArray();
1.2605 + if (useCaches) {
1.2606 + publicMethods = new SoftReference<>(res);
1.2607 + }
1.2608 + return res;
1.2609 + }
1.2610 +
1.2611 +
1.2612 + //
1.2613 + // Helpers for fetchers of one field, method, or constructor
1.2614 + //
1.2615 +
1.2616 + private Field searchFields(Field[] fields, String name) {
1.2617 + String internedName = name.intern();
1.2618 + for (int i = 0; i < fields.length; i++) {
1.2619 + if (fields[i].getName() == internedName) {
1.2620 + return getReflectionFactory().copyField(fields[i]);
1.2621 + }
1.2622 + }
1.2623 + return null;
1.2624 + }
1.2625 +
1.2626 + private Field getField0(String name) throws NoSuchFieldException {
1.2627 + // Note: the intent is that the search algorithm this routine
1.2628 + // uses be equivalent to the ordering imposed by
1.2629 + // privateGetPublicFields(). It fetches only the declared
1.2630 + // public fields for each class, however, to reduce the number
1.2631 + // of Field objects which have to be created for the common
1.2632 + // case where the field being requested is declared in the
1.2633 + // class which is being queried.
1.2634 + Field res = null;
1.2635 + // Search declared public fields
1.2636 + if ((res = searchFields(privateGetDeclaredFields(true), name)) != null) {
1.2637 + return res;
1.2638 + }
1.2639 + // Direct superinterfaces, recursively
1.2640 + Class<?>[] interfaces = getInterfaces();
1.2641 + for (int i = 0; i < interfaces.length; i++) {
1.2642 + Class<?> c = interfaces[i];
1.2643 + if ((res = c.getField0(name)) != null) {
1.2644 + return res;
1.2645 + }
1.2646 + }
1.2647 + // Direct superclass, recursively
1.2648 + if (!isInterface()) {
1.2649 + Class<?> c = getSuperclass();
1.2650 + if (c != null) {
1.2651 + if ((res = c.getField0(name)) != null) {
1.2652 + return res;
1.2653 + }
1.2654 + }
1.2655 + }
1.2656 + return null;
1.2657 + }
1.2658 +
1.2659 + private static Method searchMethods(Method[] methods,
1.2660 + String name,
1.2661 + Class<?>[] parameterTypes)
1.2662 + {
1.2663 + Method res = null;
1.2664 + String internedName = name.intern();
1.2665 + for (int i = 0; i < methods.length; i++) {
1.2666 + Method m = methods[i];
1.2667 + if (m.getName() == internedName
1.2668 + && arrayContentsEq(parameterTypes, m.getParameterTypes())
1.2669 + && (res == null
1.2670 + || res.getReturnType().isAssignableFrom(m.getReturnType())))
1.2671 + res = m;
1.2672 + }
1.2673 +
1.2674 + return (res == null ? res : getReflectionFactory().copyMethod(res));
1.2675 + }
1.2676 +
1.2677 +
1.2678 + private Method getMethod0(String name, Class<?>[] parameterTypes) {
1.2679 + // Note: the intent is that the search algorithm this routine
1.2680 + // uses be equivalent to the ordering imposed by
1.2681 + // privateGetPublicMethods(). It fetches only the declared
1.2682 + // public methods for each class, however, to reduce the
1.2683 + // number of Method objects which have to be created for the
1.2684 + // common case where the method being requested is declared in
1.2685 + // the class which is being queried.
1.2686 + Method res = null;
1.2687 + // Search declared public methods
1.2688 + if ((res = searchMethods(privateGetDeclaredMethods(true),
1.2689 + name,
1.2690 + parameterTypes)) != null) {
1.2691 + return res;
1.2692 + }
1.2693 + // Search superclass's methods
1.2694 + if (!isInterface()) {
1.2695 + Class<? super T> c = getSuperclass();
1.2696 + if (c != null) {
1.2697 + if ((res = c.getMethod0(name, parameterTypes)) != null) {
1.2698 + return res;
1.2699 + }
1.2700 + }
1.2701 + }
1.2702 + // Search superinterfaces' methods
1.2703 + Class<?>[] interfaces = getInterfaces();
1.2704 + for (int i = 0; i < interfaces.length; i++) {
1.2705 + Class<?> c = interfaces[i];
1.2706 + if ((res = c.getMethod0(name, parameterTypes)) != null) {
1.2707 + return res;
1.2708 + }
1.2709 + }
1.2710 + // Not found
1.2711 + return null;
1.2712 + }
1.2713 +
1.2714 + private Constructor<T> getConstructor0(Class<?>[] parameterTypes,
1.2715 + int which) throws NoSuchMethodException
1.2716 + {
1.2717 + Constructor<T>[] constructors = privateGetDeclaredConstructors((which == Member.PUBLIC));
1.2718 + for (Constructor<T> constructor : constructors) {
1.2719 + if (arrayContentsEq(parameterTypes,
1.2720 + constructor.getParameterTypes())) {
1.2721 + return getReflectionFactory().copyConstructor(constructor);
1.2722 + }
1.2723 + }
1.2724 + throw new NoSuchMethodException(getName() + ".<init>" + argumentTypesToString(parameterTypes));
1.2725 + }
1.2726 +
1.2727 + //
1.2728 + // Other helpers and base implementation
1.2729 + //
1.2730 +
1.2731 + private static boolean arrayContentsEq(Object[] a1, Object[] a2) {
1.2732 + if (a1 == null) {
1.2733 + return a2 == null || a2.length == 0;
1.2734 + }
1.2735 +
1.2736 + if (a2 == null) {
1.2737 + return a1.length == 0;
1.2738 + }
1.2739 +
1.2740 + if (a1.length != a2.length) {
1.2741 + return false;
1.2742 + }
1.2743 +
1.2744 + for (int i = 0; i < a1.length; i++) {
1.2745 + if (a1[i] != a2[i]) {
1.2746 + return false;
1.2747 + }
1.2748 + }
1.2749 +
1.2750 + return true;
1.2751 + }
1.2752 +
1.2753 + private static Field[] copyFields(Field[] arg) {
1.2754 + Field[] out = new Field[arg.length];
1.2755 + ReflectionFactory fact = getReflectionFactory();
1.2756 + for (int i = 0; i < arg.length; i++) {
1.2757 + out[i] = fact.copyField(arg[i]);
1.2758 + }
1.2759 + return out;
1.2760 + }
1.2761 +
1.2762 + private static Method[] copyMethods(Method[] arg) {
1.2763 + Method[] out = new Method[arg.length];
1.2764 + ReflectionFactory fact = getReflectionFactory();
1.2765 + for (int i = 0; i < arg.length; i++) {
1.2766 + out[i] = fact.copyMethod(arg[i]);
1.2767 + }
1.2768 + return out;
1.2769 + }
1.2770 +
1.2771 + private static <U> Constructor<U>[] copyConstructors(Constructor<U>[] arg) {
1.2772 + Constructor<U>[] out = arg.clone();
1.2773 + ReflectionFactory fact = getReflectionFactory();
1.2774 + for (int i = 0; i < out.length; i++) {
1.2775 + out[i] = fact.copyConstructor(out[i]);
1.2776 + }
1.2777 + return out;
1.2778 + }
1.2779 +
1.2780 + private native Field[] getDeclaredFields0(boolean publicOnly);
1.2781 + private native Method[] getDeclaredMethods0(boolean publicOnly);
1.2782 + private native Constructor<T>[] getDeclaredConstructors0(boolean publicOnly);
1.2783 + private native Class<?>[] getDeclaredClasses0();
1.2784 +
1.2785 + private static String argumentTypesToString(Class<?>[] argTypes) {
1.2786 + StringBuilder buf = new StringBuilder();
1.2787 + buf.append("(");
1.2788 + if (argTypes != null) {
1.2789 + for (int i = 0; i < argTypes.length; i++) {
1.2790 + if (i > 0) {
1.2791 + buf.append(", ");
1.2792 + }
1.2793 + Class<?> c = argTypes[i];
1.2794 + buf.append((c == null) ? "null" : c.getName());
1.2795 + }
1.2796 + }
1.2797 + buf.append(")");
1.2798 + return buf.toString();
1.2799 + }
1.2800 +
1.2801 + /** use serialVersionUID from JDK 1.1 for interoperability */
1.2802 + private static final long serialVersionUID = 3206093459760846163L;
1.2803 +
1.2804 +
1.2805 + /**
1.2806 + * Class Class is special cased within the Serialization Stream Protocol.
1.2807 + *
1.2808 + * A Class instance is written initially into an ObjectOutputStream in the
1.2809 + * following format:
1.2810 + * <pre>
1.2811 + * {@code TC_CLASS} ClassDescriptor
1.2812 + * A ClassDescriptor is a special cased serialization of
1.2813 + * a {@code java.io.ObjectStreamClass} instance.
1.2814 + * </pre>
1.2815 + * A new handle is generated for the initial time the class descriptor
1.2816 + * is written into the stream. Future references to the class descriptor
1.2817 + * are written as references to the initial class descriptor instance.
1.2818 + *
1.2819 + * @see java.io.ObjectStreamClass
1.2820 + */
1.2821 + private static final ObjectStreamField[] serialPersistentFields =
1.2822 + new ObjectStreamField[0];
1.2823 +
1.2824 +
1.2825 + /**
1.2826 + * Returns the assertion status that would be assigned to this
1.2827 + * class if it were to be initialized at the time this method is invoked.
1.2828 + * If this class has had its assertion status set, the most recent
1.2829 + * setting will be returned; otherwise, if any package default assertion
1.2830 + * status pertains to this class, the most recent setting for the most
1.2831 + * specific pertinent package default assertion status is returned;
1.2832 + * otherwise, if this class is not a system class (i.e., it has a
1.2833 + * class loader) its class loader's default assertion status is returned;
1.2834 + * otherwise, the system class default assertion status is returned.
1.2835 + * <p>
1.2836 + * Few programmers will have any need for this method; it is provided
1.2837 + * for the benefit of the JRE itself. (It allows a class to determine at
1.2838 + * the time that it is initialized whether assertions should be enabled.)
1.2839 + * Note that this method is not guaranteed to return the actual
1.2840 + * assertion status that was (or will be) associated with the specified
1.2841 + * class when it was (or will be) initialized.
1.2842 + *
1.2843 + * @return the desired assertion status of the specified class.
1.2844 + * @see java.lang.ClassLoader#setClassAssertionStatus
1.2845 + * @see java.lang.ClassLoader#setPackageAssertionStatus
1.2846 + * @see java.lang.ClassLoader#setDefaultAssertionStatus
1.2847 + * @since 1.4
1.2848 + */
1.2849 + public boolean desiredAssertionStatus() {
1.2850 + ClassLoader loader = getClassLoader();
1.2851 + // If the loader is null this is a system class, so ask the VM
1.2852 + if (loader == null)
1.2853 + return desiredAssertionStatus0(this);
1.2854 +
1.2855 + // If the classloader has been initialized with the assertion
1.2856 + // directives, ask it. Otherwise, ask the VM.
1.2857 + synchronized(loader.assertionLock) {
1.2858 + if (loader.classAssertionStatus != null) {
1.2859 + return loader.desiredAssertionStatus(getName());
1.2860 + }
1.2861 + }
1.2862 + return desiredAssertionStatus0(this);
1.2863 + }
1.2864 +
1.2865 + // Retrieves the desired assertion status of this class from the VM
1.2866 + private static native boolean desiredAssertionStatus0(Class<?> clazz);
1.2867 +
1.2868 + /**
1.2869 + * Returns true if and only if this class was declared as an enum in the
1.2870 + * source code.
1.2871 + *
1.2872 + * @return true if and only if this class was declared as an enum in the
1.2873 + * source code
1.2874 + * @since 1.5
1.2875 + */
1.2876 + public boolean isEnum() {
1.2877 + // An enum must both directly extend java.lang.Enum and have
1.2878 + // the ENUM bit set; classes for specialized enum constants
1.2879 + // don't do the former.
1.2880 + return (this.getModifiers() & ENUM) != 0 &&
1.2881 + this.getSuperclass() == java.lang.Enum.class;
1.2882 + }
1.2883 +
1.2884 + // Fetches the factory for reflective objects
1.2885 + private static ReflectionFactory getReflectionFactory() {
1.2886 + if (reflectionFactory == null) {
1.2887 + reflectionFactory =
1.2888 + java.security.AccessController.doPrivileged
1.2889 + (new sun.reflect.ReflectionFactory.GetReflectionFactoryAction());
1.2890 + }
1.2891 + return reflectionFactory;
1.2892 + }
1.2893 + private static ReflectionFactory reflectionFactory;
1.2894 +
1.2895 + // To be able to query system properties as soon as they're available
1.2896 + private static boolean initted = false;
1.2897 + private static void checkInitted() {
1.2898 + if (initted) return;
1.2899 + AccessController.doPrivileged(new PrivilegedAction<Void>() {
1.2900 + public Void run() {
1.2901 + // Tests to ensure the system properties table is fully
1.2902 + // initialized. This is needed because reflection code is
1.2903 + // called very early in the initialization process (before
1.2904 + // command-line arguments have been parsed and therefore
1.2905 + // these user-settable properties installed.) We assume that
1.2906 + // if System.out is non-null then the System class has been
1.2907 + // fully initialized and that the bulk of the startup code
1.2908 + // has been run.
1.2909 +
1.2910 + if (System.out == null) {
1.2911 + // java.lang.System not yet fully initialized
1.2912 + return null;
1.2913 + }
1.2914 +
1.2915 + String val =
1.2916 + System.getProperty("sun.reflect.noCaches");
1.2917 + if (val != null && val.equals("true")) {
1.2918 + useCaches = false;
1.2919 + }
1.2920 +
1.2921 + initted = true;
1.2922 + return null;
1.2923 + }
1.2924 + });
1.2925 + }
1.2926 +
1.2927 + /**
1.2928 + * Returns the elements of this enum class or null if this
1.2929 + * Class object does not represent an enum type.
1.2930 + *
1.2931 + * @return an array containing the values comprising the enum class
1.2932 + * represented by this Class object in the order they're
1.2933 + * declared, or null if this Class object does not
1.2934 + * represent an enum type
1.2935 + * @since 1.5
1.2936 + */
1.2937 + public T[] getEnumConstants() {
1.2938 + T[] values = getEnumConstantsShared();
1.2939 + return (values != null) ? values.clone() : null;
1.2940 + }
1.2941 +
1.2942 + /**
1.2943 + * Returns the elements of this enum class or null if this
1.2944 + * Class object does not represent an enum type;
1.2945 + * identical to getEnumConstants except that the result is
1.2946 + * uncloned, cached, and shared by all callers.
1.2947 + */
1.2948 + T[] getEnumConstantsShared() {
1.2949 + if (enumConstants == null) {
1.2950 + if (!isEnum()) return null;
1.2951 + try {
1.2952 + final Method values = getMethod("values");
1.2953 + java.security.AccessController.doPrivileged(
1.2954 + new java.security.PrivilegedAction<Void>() {
1.2955 + public Void run() {
1.2956 + values.setAccessible(true);
1.2957 + return null;
1.2958 + }
1.2959 + });
1.2960 + enumConstants = (T[])values.invoke(null);
1.2961 + }
1.2962 + // These can happen when users concoct enum-like classes
1.2963 + // that don't comply with the enum spec.
1.2964 + catch (InvocationTargetException ex) { return null; }
1.2965 + catch (NoSuchMethodException ex) { return null; }
1.2966 + catch (IllegalAccessException ex) { return null; }
1.2967 + }
1.2968 + return enumConstants;
1.2969 + }
1.2970 + private volatile transient T[] enumConstants = null;
1.2971 +
1.2972 + /**
1.2973 + * Returns a map from simple name to enum constant. This package-private
1.2974 + * method is used internally by Enum to implement
1.2975 + * public static <T extends Enum<T>> T valueOf(Class<T>, String)
1.2976 + * efficiently. Note that the map is returned by this method is
1.2977 + * created lazily on first use. Typically it won't ever get created.
1.2978 + */
1.2979 + Map<String, T> enumConstantDirectory() {
1.2980 + if (enumConstantDirectory == null) {
1.2981 + T[] universe = getEnumConstantsShared();
1.2982 + if (universe == null)
1.2983 + throw new IllegalArgumentException(
1.2984 + getName() + " is not an enum type");
1.2985 + Map<String, T> m = new HashMap<>(2 * universe.length);
1.2986 + for (T constant : universe)
1.2987 + m.put(((Enum<?>)constant).name(), constant);
1.2988 + enumConstantDirectory = m;
1.2989 + }
1.2990 + return enumConstantDirectory;
1.2991 + }
1.2992 + private volatile transient Map<String, T> enumConstantDirectory = null;
1.2993 +
1.2994 + /**
1.2995 + * Casts an object to the class or interface represented
1.2996 + * by this {@code Class} object.
1.2997 + *
1.2998 + * @param obj the object to be cast
1.2999 + * @return the object after casting, or null if obj is null
1.3000 + *
1.3001 + * @throws ClassCastException if the object is not
1.3002 + * null and is not assignable to the type T.
1.3003 + *
1.3004 + * @since 1.5
1.3005 + */
1.3006 + public T cast(Object obj) {
1.3007 + if (obj != null && !isInstance(obj))
1.3008 + throw new ClassCastException(cannotCastMsg(obj));
1.3009 + return (T) obj;
1.3010 + }
1.3011 +
1.3012 + private String cannotCastMsg(Object obj) {
1.3013 + return "Cannot cast " + obj.getClass().getName() + " to " + getName();
1.3014 + }
1.3015 +
1.3016 + /**
1.3017 + * Casts this {@code Class} object to represent a subclass of the class
1.3018 + * represented by the specified class object. Checks that that the cast
1.3019 + * is valid, and throws a {@code ClassCastException} if it is not. If
1.3020 + * this method succeeds, it always returns a reference to this class object.
1.3021 + *
1.3022 + * <p>This method is useful when a client needs to "narrow" the type of
1.3023 + * a {@code Class} object to pass it to an API that restricts the
1.3024 + * {@code Class} objects that it is willing to accept. A cast would
1.3025 + * generate a compile-time warning, as the correctness of the cast
1.3026 + * could not be checked at runtime (because generic types are implemented
1.3027 + * by erasure).
1.3028 + *
1.3029 + * @return this {@code Class} object, cast to represent a subclass of
1.3030 + * the specified class object.
1.3031 + * @throws ClassCastException if this {@code Class} object does not
1.3032 + * represent a subclass of the specified class (here "subclass" includes
1.3033 + * the class itself).
1.3034 + * @since 1.5
1.3035 + */
1.3036 + public <U> Class<? extends U> asSubclass(Class<U> clazz) {
1.3037 + if (clazz.isAssignableFrom(this))
1.3038 + return (Class<? extends U>) this;
1.3039 + else
1.3040 + throw new ClassCastException(this.toString());
1.3041 + }
1.3042 +
1.3043 + /**
1.3044 + * @throws NullPointerException {@inheritDoc}
1.3045 + * @since 1.5
1.3046 + */
1.3047 + public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {
1.3048 + if (annotationClass == null)
1.3049 + throw new NullPointerException();
1.3050 +
1.3051 + initAnnotationsIfNecessary();
1.3052 + return (A) annotations.get(annotationClass);
1.3053 + }
1.3054 +
1.3055 + /**
1.3056 + * @throws NullPointerException {@inheritDoc}
1.3057 + * @since 1.5
1.3058 + */
1.3059 + public boolean isAnnotationPresent(
1.3060 + Class<? extends Annotation> annotationClass) {
1.3061 + if (annotationClass == null)
1.3062 + throw new NullPointerException();
1.3063 +
1.3064 + return getAnnotation(annotationClass) != null;
1.3065 + }
1.3066 +
1.3067 +
1.3068 + /**
1.3069 + * @since 1.5
1.3070 + */
1.3071 + public Annotation[] getAnnotations() {
1.3072 + initAnnotationsIfNecessary();
1.3073 + return AnnotationParser.toArray(annotations);
1.3074 + }
1.3075 +
1.3076 + /**
1.3077 + * @since 1.5
1.3078 + */
1.3079 + public Annotation[] getDeclaredAnnotations() {
1.3080 + initAnnotationsIfNecessary();
1.3081 + return AnnotationParser.toArray(declaredAnnotations);
1.3082 + }
1.3083 +
1.3084 + // Annotations cache
1.3085 + private transient Map<Class<? extends Annotation>, Annotation> annotations;
1.3086 + private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
1.3087 +
1.3088 + private synchronized void initAnnotationsIfNecessary() {
1.3089 + clearCachesOnClassRedefinition();
1.3090 + if (annotations != null)
1.3091 + return;
1.3092 + declaredAnnotations = AnnotationParser.parseAnnotations(
1.3093 + getRawAnnotations(), getConstantPool(), this);
1.3094 + Class<?> superClass = getSuperclass();
1.3095 + if (superClass == null) {
1.3096 + annotations = declaredAnnotations;
1.3097 + } else {
1.3098 + annotations = new HashMap<>();
1.3099 + superClass.initAnnotationsIfNecessary();
1.3100 + for (Map.Entry<Class<? extends Annotation>, Annotation> e : superClass.annotations.entrySet()) {
1.3101 + Class<? extends Annotation> annotationClass = e.getKey();
1.3102 + if (AnnotationType.getInstance(annotationClass).isInherited())
1.3103 + annotations.put(annotationClass, e.getValue());
1.3104 + }
1.3105 + annotations.putAll(declaredAnnotations);
1.3106 + }
1.3107 + }
1.3108 +
1.3109 + // Annotation types cache their internal (AnnotationType) form
1.3110 +
1.3111 + private AnnotationType annotationType;
1.3112 +
1.3113 + void setAnnotationType(AnnotationType type) {
1.3114 + annotationType = type;
1.3115 + }
1.3116 +
1.3117 + AnnotationType getAnnotationType() {
1.3118 + return annotationType;
1.3119 + }
1.3120 +}