feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
309
jdkSrc/jdk8/java/lang/reflect/AccessibleObject.java
Normal file
309
jdkSrc/jdk8/java/lang/reflect/AccessibleObject.java
Normal file
@@ -0,0 +1,309 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang.reflect;
|
||||
|
||||
import java.security.AccessController;
|
||||
import sun.reflect.Reflection;
|
||||
import sun.reflect.ReflectionFactory;
|
||||
import java.lang.annotation.Annotation;
|
||||
|
||||
/**
|
||||
* The AccessibleObject class is the base class for Field, Method and
|
||||
* Constructor objects. It provides the ability to flag a reflected
|
||||
* object as suppressing default Java language access control checks
|
||||
* when it is used. The access checks--for public, default (package)
|
||||
* access, protected, and private members--are performed when Fields,
|
||||
* Methods or Constructors are used to set or get fields, to invoke
|
||||
* methods, or to create and initialize new instances of classes,
|
||||
* respectively.
|
||||
*
|
||||
* <p>Setting the {@code accessible} flag in a reflected object
|
||||
* permits sophisticated applications with sufficient privilege, such
|
||||
* as Java Object Serialization or other persistence mechanisms, to
|
||||
* manipulate objects in a manner that would normally be prohibited.
|
||||
*
|
||||
* <p>By default, a reflected object is <em>not</em> accessible.
|
||||
*
|
||||
* @see Field
|
||||
* @see Method
|
||||
* @see Constructor
|
||||
* @see ReflectPermission
|
||||
*
|
||||
* @since 1.2
|
||||
*/
|
||||
public class AccessibleObject implements AnnotatedElement {
|
||||
|
||||
/**
|
||||
* The Permission object that is used to check whether a client
|
||||
* has sufficient privilege to defeat Java language access
|
||||
* control checks.
|
||||
*/
|
||||
static final private java.security.Permission ACCESS_PERMISSION =
|
||||
new ReflectPermission("suppressAccessChecks");
|
||||
|
||||
/**
|
||||
* Convenience method to set the {@code accessible} flag for an
|
||||
* array of objects with a single security check (for efficiency).
|
||||
*
|
||||
* <p>First, if there is a security manager, its
|
||||
* {@code checkPermission} method is called with a
|
||||
* {@code ReflectPermission("suppressAccessChecks")} permission.
|
||||
*
|
||||
* <p>A {@code SecurityException} is raised if {@code flag} is
|
||||
* {@code true} but accessibility of any of the elements of the input
|
||||
* {@code array} may not be changed (for example, if the element
|
||||
* object is a {@link Constructor} object for the class {@link
|
||||
* java.lang.Class}). In the event of such a SecurityException, the
|
||||
* accessibility of objects is set to {@code flag} for array elements
|
||||
* upto (and excluding) the element for which the exception occurred; the
|
||||
* accessibility of elements beyond (and including) the element for which
|
||||
* the exception occurred is unchanged.
|
||||
*
|
||||
* @param array the array of AccessibleObjects
|
||||
* @param flag the new value for the {@code accessible} flag
|
||||
* in each object
|
||||
* @throws SecurityException if the request is denied.
|
||||
* @see SecurityManager#checkPermission
|
||||
* @see java.lang.RuntimePermission
|
||||
*/
|
||||
public static void setAccessible(AccessibleObject[] array, boolean flag)
|
||||
throws SecurityException {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) sm.checkPermission(ACCESS_PERMISSION);
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
setAccessible0(array[i], flag);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@code accessible} flag for this object to
|
||||
* the indicated boolean value. A value of {@code true} indicates that
|
||||
* the reflected object should suppress Java language access
|
||||
* checking when it is used. A value of {@code false} indicates
|
||||
* that the reflected object should enforce Java language access checks.
|
||||
*
|
||||
* <p>First, if there is a security manager, its
|
||||
* {@code checkPermission} method is called with a
|
||||
* {@code ReflectPermission("suppressAccessChecks")} permission.
|
||||
*
|
||||
* <p>A {@code SecurityException} is raised if {@code flag} is
|
||||
* {@code true} but accessibility of this object may not be changed
|
||||
* (for example, if this element object is a {@link Constructor} object for
|
||||
* the class {@link java.lang.Class}).
|
||||
*
|
||||
* <p>A {@code SecurityException} is raised if this object is a {@link
|
||||
* java.lang.reflect.Constructor} object for the class
|
||||
* {@code java.lang.Class}, and {@code flag} is true.
|
||||
*
|
||||
* @param flag the new value for the {@code accessible} flag
|
||||
* @throws SecurityException if the request is denied.
|
||||
* @see SecurityManager#checkPermission
|
||||
* @see java.lang.RuntimePermission
|
||||
*/
|
||||
public void setAccessible(boolean flag) throws SecurityException {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) sm.checkPermission(ACCESS_PERMISSION);
|
||||
setAccessible0(this, flag);
|
||||
}
|
||||
|
||||
/* Check that you aren't exposing java.lang.Class.<init> or sensitive
|
||||
fields in java.lang.Class. */
|
||||
private static void setAccessible0(AccessibleObject obj, boolean flag)
|
||||
throws SecurityException
|
||||
{
|
||||
if (obj instanceof Constructor && flag == true) {
|
||||
Constructor<?> c = (Constructor<?>)obj;
|
||||
if (c.getDeclaringClass() == Class.class) {
|
||||
throw new SecurityException("Cannot make a java.lang.Class" +
|
||||
" constructor accessible");
|
||||
}
|
||||
}
|
||||
obj.override = flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of the {@code accessible} flag for this object.
|
||||
*
|
||||
* @return the value of the object's {@code accessible} flag
|
||||
*/
|
||||
public boolean isAccessible() {
|
||||
return override;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor: only used by the Java Virtual Machine.
|
||||
*/
|
||||
protected AccessibleObject() {}
|
||||
|
||||
// Indicates whether language-level access checks are overridden
|
||||
// by this object. Initializes to "false". This field is used by
|
||||
// Field, Method, and Constructor.
|
||||
//
|
||||
// NOTE: for security purposes, this field must not be visible
|
||||
// outside this package.
|
||||
boolean override;
|
||||
|
||||
// Reflection factory used by subclasses for creating field,
|
||||
// method, and constructor accessors. Note that this is called
|
||||
// very early in the bootstrapping process.
|
||||
static final ReflectionFactory reflectionFactory =
|
||||
AccessController.doPrivileged(
|
||||
new sun.reflect.ReflectionFactory.GetReflectionFactoryAction());
|
||||
|
||||
/**
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
* @since 1.5
|
||||
*/
|
||||
public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
|
||||
throw new AssertionError("All subclasses should override this method");
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
* @since 1.5
|
||||
*/
|
||||
@Override
|
||||
public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
|
||||
return AnnotatedElement.super.isAnnotationPresent(annotationClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
* @since 1.8
|
||||
*/
|
||||
@Override
|
||||
public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
|
||||
throw new AssertionError("All subclasses should override this method");
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 1.5
|
||||
*/
|
||||
public Annotation[] getAnnotations() {
|
||||
return getDeclaredAnnotations();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
* @since 1.8
|
||||
*/
|
||||
@Override
|
||||
public <T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass) {
|
||||
// Only annotations on classes are inherited, for all other
|
||||
// objects getDeclaredAnnotation is the same as
|
||||
// getAnnotation.
|
||||
return getAnnotation(annotationClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
* @since 1.8
|
||||
*/
|
||||
@Override
|
||||
public <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass) {
|
||||
// Only annotations on classes are inherited, for all other
|
||||
// objects getDeclaredAnnotationsByType is the same as
|
||||
// getAnnotationsByType.
|
||||
return getAnnotationsByType(annotationClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 1.5
|
||||
*/
|
||||
public Annotation[] getDeclaredAnnotations() {
|
||||
throw new AssertionError("All subclasses should override this method");
|
||||
}
|
||||
|
||||
|
||||
// Shared access checking logic.
|
||||
|
||||
// For non-public members or members in package-private classes,
|
||||
// it is necessary to perform somewhat expensive security checks.
|
||||
// If the security check succeeds for a given class, it will
|
||||
// always succeed (it is not affected by the granting or revoking
|
||||
// of permissions); we speed up the check in the common case by
|
||||
// remembering the last Class for which the check succeeded.
|
||||
//
|
||||
// The simple security check for Constructor is to see if
|
||||
// the caller has already been seen, verified, and cached.
|
||||
// (See also Class.newInstance(), which uses a similar method.)
|
||||
//
|
||||
// A more complicated security check cache is needed for Method and Field
|
||||
// The cache can be either null (empty cache), a 2-array of {caller,target},
|
||||
// or a caller (with target implicitly equal to this.clazz).
|
||||
// In the 2-array case, the target is always different from the clazz.
|
||||
volatile Object securityCheckCache;
|
||||
|
||||
void checkAccess(Class<?> caller, Class<?> clazz, Object obj, int modifiers)
|
||||
throws IllegalAccessException
|
||||
{
|
||||
if (caller == clazz) { // quick check
|
||||
return; // ACCESS IS OK
|
||||
}
|
||||
Object cache = securityCheckCache; // read volatile
|
||||
Class<?> targetClass = clazz;
|
||||
if (obj != null
|
||||
&& Modifier.isProtected(modifiers)
|
||||
&& ((targetClass = obj.getClass()) != clazz)) {
|
||||
// Must match a 2-list of { caller, targetClass }.
|
||||
if (cache instanceof Class[]) {
|
||||
Class<?>[] cache2 = (Class<?>[]) cache;
|
||||
if (cache2[1] == targetClass &&
|
||||
cache2[0] == caller) {
|
||||
return; // ACCESS IS OK
|
||||
}
|
||||
// (Test cache[1] first since range check for [1]
|
||||
// subsumes range check for [0].)
|
||||
}
|
||||
} else if (cache == caller) {
|
||||
// Non-protected case (or obj.class == this.clazz).
|
||||
return; // ACCESS IS OK
|
||||
}
|
||||
|
||||
// If no return, fall through to the slow path.
|
||||
slowCheckMemberAccess(caller, clazz, obj, modifiers, targetClass);
|
||||
}
|
||||
|
||||
// Keep all this slow stuff out of line:
|
||||
void slowCheckMemberAccess(Class<?> caller, Class<?> clazz, Object obj, int modifiers,
|
||||
Class<?> targetClass)
|
||||
throws IllegalAccessException
|
||||
{
|
||||
Reflection.ensureMemberAccess(caller, clazz, obj, modifiers);
|
||||
|
||||
// Success: Update the cache.
|
||||
Object cache = ((targetClass == clazz)
|
||||
? caller
|
||||
: new Class<?>[] { caller, targetClass });
|
||||
|
||||
// Note: The two cache elements are not volatile,
|
||||
// but they are effectively final. The Java memory model
|
||||
// guarantees that the initializing stores for the cache
|
||||
// elements will occur before the volatile write.
|
||||
securityCheckCache = cache; // write volatile
|
||||
}
|
||||
}
|
||||
44
jdkSrc/jdk8/java/lang/reflect/AnnotatedArrayType.java
Normal file
44
jdkSrc/jdk8/java/lang/reflect/AnnotatedArrayType.java
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang.reflect;
|
||||
|
||||
|
||||
/**
|
||||
* {@code AnnotatedArrayType} represents the potentially annotated use of an
|
||||
* array type, whose component type may itself represent the annotated use of a
|
||||
* type.
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
public interface AnnotatedArrayType extends AnnotatedType {
|
||||
|
||||
/**
|
||||
* Returns the potentially annotated generic component type of this array type.
|
||||
*
|
||||
* @return the potentially annotated generic component type of this array type
|
||||
*/
|
||||
AnnotatedType getAnnotatedGenericComponentType();
|
||||
}
|
||||
450
jdkSrc/jdk8/java/lang/reflect/AnnotatedElement.java
Normal file
450
jdkSrc/jdk8/java/lang/reflect/AnnotatedElement.java
Normal file
@@ -0,0 +1,450 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang.reflect;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.annotation.AnnotationFormatError;
|
||||
import java.lang.annotation.Repeatable;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import sun.reflect.annotation.AnnotationSupport;
|
||||
import sun.reflect.annotation.AnnotationType;
|
||||
|
||||
/**
|
||||
* Represents an annotated element of the program currently running in this
|
||||
* VM. This interface allows annotations to be read reflectively. All
|
||||
* annotations returned by methods in this interface are immutable and
|
||||
* serializable. The arrays returned by methods of this interface may be modified
|
||||
* by callers without affecting the arrays returned to other callers.
|
||||
*
|
||||
* <p>The {@link #getAnnotationsByType(Class)} and {@link
|
||||
* #getDeclaredAnnotationsByType(Class)} methods support multiple
|
||||
* annotations of the same type on an element. If the argument to
|
||||
* either method is a repeatable annotation type (JLS 9.6), then the
|
||||
* method will "look through" a container annotation (JLS 9.7), if
|
||||
* present, and return any annotations inside the container. Container
|
||||
* annotations may be generated at compile-time to wrap multiple
|
||||
* annotations of the argument type.
|
||||
*
|
||||
* <p>The terms <em>directly present</em>, <em>indirectly present</em>,
|
||||
* <em>present</em>, and <em>associated</em> are used throughout this
|
||||
* interface to describe precisely which annotations are returned by
|
||||
* methods:
|
||||
*
|
||||
* <ul>
|
||||
*
|
||||
* <li> An annotation <i>A</i> is <em>directly present</em> on an
|
||||
* element <i>E</i> if <i>E</i> has a {@code
|
||||
* RuntimeVisibleAnnotations} or {@code
|
||||
* RuntimeVisibleParameterAnnotations} or {@code
|
||||
* RuntimeVisibleTypeAnnotations} attribute, and the attribute
|
||||
* contains <i>A</i>.
|
||||
*
|
||||
* <li>An annotation <i>A</i> is <em>indirectly present</em> on an
|
||||
* element <i>E</i> if <i>E</i> has a {@code RuntimeVisibleAnnotations} or
|
||||
* {@code RuntimeVisibleParameterAnnotations} or {@code RuntimeVisibleTypeAnnotations}
|
||||
* attribute, and <i>A</i> 's type is repeatable, and the attribute contains
|
||||
* exactly one annotation whose value element contains <i>A</i> and whose
|
||||
* type is the containing annotation type of <i>A</i> 's type.
|
||||
*
|
||||
* <li>An annotation <i>A</i> is present on an element <i>E</i> if either:
|
||||
*
|
||||
* <ul>
|
||||
*
|
||||
* <li><i>A</i> is directly present on <i>E</i>; or
|
||||
*
|
||||
* <li>No annotation of <i>A</i> 's type is directly present on
|
||||
* <i>E</i>, and <i>E</i> is a class, and <i>A</i> 's type is
|
||||
* inheritable, and <i>A</i> is present on the superclass of <i>E</i>.
|
||||
*
|
||||
* </ul>
|
||||
*
|
||||
* <li>An annotation <i>A</i> is <em>associated</em> with an element <i>E</i>
|
||||
* if either:
|
||||
*
|
||||
* <ul>
|
||||
*
|
||||
* <li><i>A</i> is directly or indirectly present on <i>E</i>; or
|
||||
*
|
||||
* <li>No annotation of <i>A</i> 's type is directly or indirectly
|
||||
* present on <i>E</i>, and <i>E</i> is a class, and <i>A</i>'s type
|
||||
* is inheritable, and <i>A</i> is associated with the superclass of
|
||||
* <i>E</i>.
|
||||
*
|
||||
* </ul>
|
||||
*
|
||||
* </ul>
|
||||
*
|
||||
* <p>The table below summarizes which kind of annotation presence
|
||||
* different methods in this interface examine.
|
||||
*
|
||||
* <table border>
|
||||
* <caption>Overview of kind of presence detected by different AnnotatedElement methods</caption>
|
||||
* <tr><th colspan=2></th><th colspan=4>Kind of Presence</th>
|
||||
* <tr><th colspan=2>Method</th><th>Directly Present</th><th>Indirectly Present</th><th>Present</th><th>Associated</th>
|
||||
* <tr><td align=right>{@code T}</td><td>{@link #getAnnotation(Class) getAnnotation(Class<T>)}
|
||||
* <td></td><td></td><td>X</td><td></td>
|
||||
* </tr>
|
||||
* <tr><td align=right>{@code Annotation[]}</td><td>{@link #getAnnotations getAnnotations()}
|
||||
* <td></td><td></td><td>X</td><td></td>
|
||||
* </tr>
|
||||
* <tr><td align=right>{@code T[]}</td><td>{@link #getAnnotationsByType(Class) getAnnotationsByType(Class<T>)}
|
||||
* <td></td><td></td><td></td><td>X</td>
|
||||
* </tr>
|
||||
* <tr><td align=right>{@code T}</td><td>{@link #getDeclaredAnnotation(Class) getDeclaredAnnotation(Class<T>)}
|
||||
* <td>X</td><td></td><td></td><td></td>
|
||||
* </tr>
|
||||
* <tr><td align=right>{@code Annotation[]}</td><td>{@link #getDeclaredAnnotations getDeclaredAnnotations()}
|
||||
* <td>X</td><td></td><td></td><td></td>
|
||||
* </tr>
|
||||
* <tr><td align=right>{@code T[]}</td><td>{@link #getDeclaredAnnotationsByType(Class) getDeclaredAnnotationsByType(Class<T>)}
|
||||
* <td>X</td><td>X</td><td></td><td></td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* <p>For an invocation of {@code get[Declared]AnnotationsByType( Class <
|
||||
* T >)}, the order of annotations which are directly or indirectly
|
||||
* present on an element <i>E</i> is computed as if indirectly present
|
||||
* annotations on <i>E</i> are directly present on <i>E</i> in place
|
||||
* of their container annotation, in the order in which they appear in
|
||||
* the value element of the container annotation.
|
||||
*
|
||||
* <p>There are several compatibility concerns to keep in mind if an
|
||||
* annotation type <i>T</i> is originally <em>not</em> repeatable and
|
||||
* later modified to be repeatable.
|
||||
*
|
||||
* The containing annotation type for <i>T</i> is <i>TC</i>.
|
||||
*
|
||||
* <ul>
|
||||
*
|
||||
* <li>Modifying <i>T</i> to be repeatable is source and binary
|
||||
* compatible with existing uses of <i>T</i> and with existing uses
|
||||
* of <i>TC</i>.
|
||||
*
|
||||
* That is, for source compatibility, source code with annotations of
|
||||
* type <i>T</i> or of type <i>TC</i> will still compile. For binary
|
||||
* compatibility, class files with annotations of type <i>T</i> or of
|
||||
* type <i>TC</i> (or with other kinds of uses of type <i>T</i> or of
|
||||
* type <i>TC</i>) will link against the modified version of <i>T</i>
|
||||
* if they linked against the earlier version.
|
||||
*
|
||||
* (An annotation type <i>TC</i> may informally serve as an acting
|
||||
* containing annotation type before <i>T</i> is modified to be
|
||||
* formally repeatable. Alternatively, when <i>T</i> is made
|
||||
* repeatable, <i>TC</i> can be introduced as a new type.)
|
||||
*
|
||||
* <li>If an annotation type <i>TC</i> is present on an element, and
|
||||
* <i>T</i> is modified to be repeatable with <i>TC</i> as its
|
||||
* containing annotation type then:
|
||||
*
|
||||
* <ul>
|
||||
*
|
||||
* <li>The change to <i>T</i> is behaviorally compatible with respect
|
||||
* to the {@code get[Declared]Annotation(Class<T>)} (called with an
|
||||
* argument of <i>T</i> or <i>TC</i>) and {@code
|
||||
* get[Declared]Annotations()} methods because the results of the
|
||||
* methods will not change due to <i>TC</i> becoming the containing
|
||||
* annotation type for <i>T</i>.
|
||||
*
|
||||
* <li>The change to <i>T</i> changes the results of the {@code
|
||||
* get[Declared]AnnotationsByType(Class<T>)} methods called with an
|
||||
* argument of <i>T</i>, because those methods will now recognize an
|
||||
* annotation of type <i>TC</i> as a container annotation for <i>T</i>
|
||||
* and will "look through" it to expose annotations of type <i>T</i>.
|
||||
*
|
||||
* </ul>
|
||||
*
|
||||
* <li>If an annotation of type <i>T</i> is present on an
|
||||
* element and <i>T</i> is made repeatable and more annotations of
|
||||
* type <i>T</i> are added to the element:
|
||||
*
|
||||
* <ul>
|
||||
*
|
||||
* <li> The addition of the annotations of type <i>T</i> is both
|
||||
* source compatible and binary compatible.
|
||||
*
|
||||
* <li>The addition of the annotations of type <i>T</i> changes the results
|
||||
* of the {@code get[Declared]Annotation(Class<T>)} methods and {@code
|
||||
* get[Declared]Annotations()} methods, because those methods will now
|
||||
* only see a container annotation on the element and not see an
|
||||
* annotation of type <i>T</i>.
|
||||
*
|
||||
* <li>The addition of the annotations of type <i>T</i> changes the
|
||||
* results of the {@code get[Declared]AnnotationsByType(Class<T>)}
|
||||
* methods, because their results will expose the additional
|
||||
* annotations of type <i>T</i> whereas previously they exposed only a
|
||||
* single annotation of type <i>T</i>.
|
||||
*
|
||||
* </ul>
|
||||
*
|
||||
* </ul>
|
||||
*
|
||||
* <p>If an annotation returned by a method in this interface contains
|
||||
* (directly or indirectly) a {@link Class}-valued member referring to
|
||||
* a class that is not accessible in this VM, attempting to read the class
|
||||
* by calling the relevant Class-returning method on the returned annotation
|
||||
* will result in a {@link TypeNotPresentException}.
|
||||
*
|
||||
* <p>Similarly, attempting to read an enum-valued member will result in
|
||||
* a {@link EnumConstantNotPresentException} if the enum constant in the
|
||||
* annotation is no longer present in the enum type.
|
||||
*
|
||||
* <p>If an annotation type <i>T</i> is (meta-)annotated with an
|
||||
* {@code @Repeatable} annotation whose value element indicates a type
|
||||
* <i>TC</i>, but <i>TC</i> does not declare a {@code value()} method
|
||||
* with a return type of <i>T</i>{@code []}, then an exception of type
|
||||
* {@link java.lang.annotation.AnnotationFormatError} is thrown.
|
||||
*
|
||||
* <p>Finally, attempting to read a member whose definition has evolved
|
||||
* incompatibly will result in a {@link
|
||||
* java.lang.annotation.AnnotationTypeMismatchException} or an
|
||||
* {@link java.lang.annotation.IncompleteAnnotationException}.
|
||||
*
|
||||
* @see java.lang.EnumConstantNotPresentException
|
||||
* @see java.lang.TypeNotPresentException
|
||||
* @see AnnotationFormatError
|
||||
* @see java.lang.annotation.AnnotationTypeMismatchException
|
||||
* @see java.lang.annotation.IncompleteAnnotationException
|
||||
* @since 1.5
|
||||
* @author Josh Bloch
|
||||
*/
|
||||
public interface AnnotatedElement {
|
||||
/**
|
||||
* Returns true if an annotation for the specified type
|
||||
* is <em>present</em> on this element, else false. This method
|
||||
* is designed primarily for convenient access to marker annotations.
|
||||
*
|
||||
* <p>The truth value returned by this method is equivalent to:
|
||||
* {@code getAnnotation(annotationClass) != null}
|
||||
*
|
||||
* <p>The body of the default method is specified to be the code
|
||||
* above.
|
||||
*
|
||||
* @param annotationClass the Class object corresponding to the
|
||||
* annotation type
|
||||
* @return true if an annotation for the specified annotation
|
||||
* type is present on this element, else false
|
||||
* @throws NullPointerException if the given annotation class is null
|
||||
* @since 1.5
|
||||
*/
|
||||
default boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
|
||||
return getAnnotation(annotationClass) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this element's annotation for the specified type if
|
||||
* such an annotation is <em>present</em>, else null.
|
||||
*
|
||||
* @param <T> the type of the annotation to query for and return if present
|
||||
* @param annotationClass the Class object corresponding to the
|
||||
* annotation type
|
||||
* @return this element's annotation for the specified annotation type if
|
||||
* present on this element, else null
|
||||
* @throws NullPointerException if the given annotation class is null
|
||||
* @since 1.5
|
||||
*/
|
||||
<T extends Annotation> T getAnnotation(Class<T> annotationClass);
|
||||
|
||||
/**
|
||||
* Returns annotations that are <em>present</em> on this element.
|
||||
*
|
||||
* If there are no annotations <em>present</em> on this element, the return
|
||||
* value is an array of length 0.
|
||||
*
|
||||
* The caller of this method is free to modify the returned array; it will
|
||||
* have no effect on the arrays returned to other callers.
|
||||
*
|
||||
* @return annotations present on this element
|
||||
* @since 1.5
|
||||
*/
|
||||
Annotation[] getAnnotations();
|
||||
|
||||
/**
|
||||
* Returns annotations that are <em>associated</em> with this element.
|
||||
*
|
||||
* If there are no annotations <em>associated</em> with this element, the return
|
||||
* value is an array of length 0.
|
||||
*
|
||||
* The difference between this method and {@link #getAnnotation(Class)}
|
||||
* is that this method detects if its argument is a <em>repeatable
|
||||
* annotation type</em> (JLS 9.6), and if so, attempts to find one or
|
||||
* more annotations of that type by "looking through" a container
|
||||
* annotation.
|
||||
*
|
||||
* The caller of this method is free to modify the returned array; it will
|
||||
* have no effect on the arrays returned to other callers.
|
||||
*
|
||||
* @implSpec The default implementation first calls {@link
|
||||
* #getDeclaredAnnotationsByType(Class)} passing {@code
|
||||
* annotationClass} as the argument. If the returned array has
|
||||
* length greater than zero, the array is returned. If the returned
|
||||
* array is zero-length and this {@code AnnotatedElement} is a
|
||||
* class and the argument type is an inheritable annotation type,
|
||||
* and the superclass of this {@code AnnotatedElement} is non-null,
|
||||
* then the returned result is the result of calling {@link
|
||||
* #getAnnotationsByType(Class)} on the superclass with {@code
|
||||
* annotationClass} as the argument. Otherwise, a zero-length
|
||||
* array is returned.
|
||||
*
|
||||
* @param <T> the type of the annotation to query for and return if present
|
||||
* @param annotationClass the Class object corresponding to the
|
||||
* annotation type
|
||||
* @return all this element's annotations for the specified annotation type if
|
||||
* associated with this element, else an array of length zero
|
||||
* @throws NullPointerException if the given annotation class is null
|
||||
* @since 1.8
|
||||
*/
|
||||
default <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
|
||||
/*
|
||||
* Definition of associated: directly or indirectly present OR
|
||||
* neither directly nor indirectly present AND the element is
|
||||
* a Class, the annotation type is inheritable, and the
|
||||
* annotation type is associated with the superclass of the
|
||||
* element.
|
||||
*/
|
||||
T[] result = getDeclaredAnnotationsByType(annotationClass);
|
||||
|
||||
if (result.length == 0 && // Neither directly nor indirectly present
|
||||
this instanceof Class && // the element is a class
|
||||
AnnotationType.getInstance(annotationClass).isInherited()) { // Inheritable
|
||||
Class<?> superClass = ((Class<?>) this).getSuperclass();
|
||||
if (superClass != null) {
|
||||
// Determine if the annotation is associated with the
|
||||
// superclass
|
||||
result = superClass.getAnnotationsByType(annotationClass);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this element's annotation for the specified type if
|
||||
* such an annotation is <em>directly present</em>, else null.
|
||||
*
|
||||
* This method ignores inherited annotations. (Returns null if no
|
||||
* annotations are directly present on this element.)
|
||||
*
|
||||
* @implSpec The default implementation first performs a null check
|
||||
* and then loops over the results of {@link
|
||||
* #getDeclaredAnnotations} returning the first annotation whose
|
||||
* annotation type matches the argument type.
|
||||
*
|
||||
* @param <T> the type of the annotation to query for and return if directly present
|
||||
* @param annotationClass the Class object corresponding to the
|
||||
* annotation type
|
||||
* @return this element's annotation for the specified annotation type if
|
||||
* directly present on this element, else null
|
||||
* @throws NullPointerException if the given annotation class is null
|
||||
* @since 1.8
|
||||
*/
|
||||
default <T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass) {
|
||||
Objects.requireNonNull(annotationClass);
|
||||
// Loop over all directly-present annotations looking for a matching one
|
||||
for (Annotation annotation : getDeclaredAnnotations()) {
|
||||
if (annotationClass.equals(annotation.annotationType())) {
|
||||
// More robust to do a dynamic cast at runtime instead
|
||||
// of compile-time only.
|
||||
return annotationClass.cast(annotation);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this element's annotation(s) for the specified type if
|
||||
* such annotations are either <em>directly present</em> or
|
||||
* <em>indirectly present</em>. This method ignores inherited
|
||||
* annotations.
|
||||
*
|
||||
* If there are no specified annotations directly or indirectly
|
||||
* present on this element, the return value is an array of length
|
||||
* 0.
|
||||
*
|
||||
* The difference between this method and {@link
|
||||
* #getDeclaredAnnotation(Class)} is that this method detects if its
|
||||
* argument is a <em>repeatable annotation type</em> (JLS 9.6), and if so,
|
||||
* attempts to find one or more annotations of that type by "looking
|
||||
* through" a container annotation if one is present.
|
||||
*
|
||||
* The caller of this method is free to modify the returned array; it will
|
||||
* have no effect on the arrays returned to other callers.
|
||||
*
|
||||
* @implSpec The default implementation may call {@link
|
||||
* #getDeclaredAnnotation(Class)} one or more times to find a
|
||||
* directly present annotation and, if the annotation type is
|
||||
* repeatable, to find a container annotation. If annotations of
|
||||
* the annotation type {@code annotationClass} are found to be both
|
||||
* directly and indirectly present, then {@link
|
||||
* #getDeclaredAnnotations()} will get called to determine the
|
||||
* order of the elements in the returned array.
|
||||
*
|
||||
* <p>Alternatively, the default implementation may call {@link
|
||||
* #getDeclaredAnnotations()} a single time and the returned array
|
||||
* examined for both directly and indirectly present
|
||||
* annotations. The results of calling {@link
|
||||
* #getDeclaredAnnotations()} are assumed to be consistent with the
|
||||
* results of calling {@link #getDeclaredAnnotation(Class)}.
|
||||
*
|
||||
* @param <T> the type of the annotation to query for and return
|
||||
* if directly or indirectly present
|
||||
* @param annotationClass the Class object corresponding to the
|
||||
* annotation type
|
||||
* @return all this element's annotations for the specified annotation type if
|
||||
* directly or indirectly present on this element, else an array of length zero
|
||||
* @throws NullPointerException if the given annotation class is null
|
||||
* @since 1.8
|
||||
*/
|
||||
default <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass) {
|
||||
Objects.requireNonNull(annotationClass);
|
||||
return AnnotationSupport.
|
||||
getDirectlyAndIndirectlyPresent(Arrays.stream(getDeclaredAnnotations()).
|
||||
collect(Collectors.toMap(Annotation::annotationType,
|
||||
Function.identity(),
|
||||
((first,second) -> first),
|
||||
LinkedHashMap::new)),
|
||||
annotationClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns annotations that are <em>directly present</em> on this element.
|
||||
* This method ignores inherited annotations.
|
||||
*
|
||||
* If there are no annotations <em>directly present</em> on this element,
|
||||
* the return value is an array of length 0.
|
||||
*
|
||||
* The caller of this method is free to modify the returned array; it will
|
||||
* have no effect on the arrays returned to other callers.
|
||||
*
|
||||
* @return annotations directly present on this element
|
||||
* @since 1.5
|
||||
*/
|
||||
Annotation[] getDeclaredAnnotations();
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang.reflect;
|
||||
|
||||
/**
|
||||
* {@code AnnotatedParameterizedType} represents the potentially annotated use
|
||||
* of a parameterized type, whose type arguments may themselves represent
|
||||
* annotated uses of types.
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
public interface AnnotatedParameterizedType extends AnnotatedType {
|
||||
|
||||
/**
|
||||
* Returns the potentially annotated actual type arguments of this parameterized type.
|
||||
*
|
||||
* @return the potentially annotated actual type arguments of this parameterized type
|
||||
*/
|
||||
AnnotatedType[] getAnnotatedActualTypeArguments();
|
||||
}
|
||||
44
jdkSrc/jdk8/java/lang/reflect/AnnotatedType.java
Normal file
44
jdkSrc/jdk8/java/lang/reflect/AnnotatedType.java
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang.reflect;
|
||||
|
||||
/**
|
||||
* {@code AnnotatedType} represents the potentially annotated use of a type in
|
||||
* the program currently running in this VM. The use may be of any type in the
|
||||
* Java programming language, including an array type, a parameterized type, a
|
||||
* type variable, or a wildcard type.
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
public interface AnnotatedType extends AnnotatedElement {
|
||||
|
||||
/**
|
||||
* Returns the underlying type that this annotated type represents.
|
||||
*
|
||||
* @return the type this annotated type represents
|
||||
*/
|
||||
public Type getType();
|
||||
}
|
||||
43
jdkSrc/jdk8/java/lang/reflect/AnnotatedTypeVariable.java
Normal file
43
jdkSrc/jdk8/java/lang/reflect/AnnotatedTypeVariable.java
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang.reflect;
|
||||
|
||||
/**
|
||||
* {@code AnnotatedTypeVariable} represents the potentially annotated use of a
|
||||
* type variable, whose declaration may have bounds which themselves represent
|
||||
* annotated uses of types.
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
public interface AnnotatedTypeVariable extends AnnotatedType {
|
||||
|
||||
/**
|
||||
* Returns the potentially annotated bounds of this type variable.
|
||||
*
|
||||
* @return the potentially annotated bounds of this type variable
|
||||
*/
|
||||
AnnotatedType[] getAnnotatedBounds();
|
||||
}
|
||||
50
jdkSrc/jdk8/java/lang/reflect/AnnotatedWildcardType.java
Normal file
50
jdkSrc/jdk8/java/lang/reflect/AnnotatedWildcardType.java
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang.reflect;
|
||||
|
||||
/**
|
||||
* {@code AnnotatedWildcardType} represents the potentially annotated use of a
|
||||
* wildcard type argument, whose upper or lower bounds may themselves represent
|
||||
* annotated uses of types.
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
public interface AnnotatedWildcardType extends AnnotatedType {
|
||||
|
||||
/**
|
||||
* Returns the potentially annotated lower bounds of this wildcard type.
|
||||
*
|
||||
* @return the potentially annotated lower bounds of this wildcard type
|
||||
*/
|
||||
AnnotatedType[] getAnnotatedLowerBounds();
|
||||
|
||||
/**
|
||||
* Returns the potentially annotated upper bounds of this wildcard type.
|
||||
*
|
||||
* @return the potentially annotated upper bounds of this wildcard type
|
||||
*/
|
||||
AnnotatedType[] getAnnotatedUpperBounds();
|
||||
}
|
||||
488
jdkSrc/jdk8/java/lang/reflect/Array.java
Normal file
488
jdkSrc/jdk8/java/lang/reflect/Array.java
Normal file
@@ -0,0 +1,488 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang.reflect;
|
||||
|
||||
/**
|
||||
* The {@code Array} class provides static methods to dynamically create and
|
||||
* access Java arrays.
|
||||
*
|
||||
* <p>{@code Array} permits widening conversions to occur during a get or set
|
||||
* operation, but throws an {@code IllegalArgumentException} if a narrowing
|
||||
* conversion would occur.
|
||||
*
|
||||
* @author Nakul Saraiya
|
||||
*/
|
||||
public final
|
||||
class Array {
|
||||
|
||||
/**
|
||||
* Constructor. Class Array is not instantiable.
|
||||
*/
|
||||
private Array() {}
|
||||
|
||||
/**
|
||||
* Creates a new array with the specified component type and
|
||||
* length.
|
||||
* Invoking this method is equivalent to creating an array
|
||||
* as follows:
|
||||
* <blockquote>
|
||||
* <pre>
|
||||
* int[] x = {length};
|
||||
* Array.newInstance(componentType, x);
|
||||
* </pre>
|
||||
* </blockquote>
|
||||
*
|
||||
* <p>The number of dimensions of the new array must not
|
||||
* exceed 255.
|
||||
*
|
||||
* @param componentType the {@code Class} object representing the
|
||||
* component type of the new array
|
||||
* @param length the length of the new array
|
||||
* @return the new array
|
||||
* @exception NullPointerException if the specified
|
||||
* {@code componentType} parameter is null
|
||||
* @exception IllegalArgumentException if componentType is {@link
|
||||
* Void#TYPE} or if the number of dimensions of the requested array
|
||||
* instance exceed 255.
|
||||
* @exception NegativeArraySizeException if the specified {@code length}
|
||||
* is negative
|
||||
*/
|
||||
public static Object newInstance(Class<?> componentType, int length)
|
||||
throws NegativeArraySizeException {
|
||||
return newArray(componentType, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new array
|
||||
* with the specified component type and dimensions.
|
||||
* If {@code componentType}
|
||||
* represents a non-array class or interface, the new array
|
||||
* has {@code dimensions.length} dimensions and
|
||||
* {@code componentType} as its component type. If
|
||||
* {@code componentType} represents an array class, the
|
||||
* number of dimensions of the new array is equal to the sum
|
||||
* of {@code dimensions.length} and the number of
|
||||
* dimensions of {@code componentType}. In this case, the
|
||||
* component type of the new array is the component type of
|
||||
* {@code componentType}.
|
||||
*
|
||||
* <p>The number of dimensions of the new array must not
|
||||
* exceed 255.
|
||||
*
|
||||
* @param componentType the {@code Class} object representing the component
|
||||
* type of the new array
|
||||
* @param dimensions an array of {@code int} representing the dimensions of
|
||||
* the new array
|
||||
* @return the new array
|
||||
* @exception NullPointerException if the specified
|
||||
* {@code componentType} argument is null
|
||||
* @exception IllegalArgumentException if the specified {@code dimensions}
|
||||
* argument is a zero-dimensional array, if componentType is {@link
|
||||
* Void#TYPE}, or if the number of dimensions of the requested array
|
||||
* instance exceed 255.
|
||||
* @exception NegativeArraySizeException if any of the components in
|
||||
* the specified {@code dimensions} argument is negative.
|
||||
*/
|
||||
public static Object newInstance(Class<?> componentType, int... dimensions)
|
||||
throws IllegalArgumentException, NegativeArraySizeException {
|
||||
return multiNewArray(componentType, dimensions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length of the specified array object, as an {@code int}.
|
||||
*
|
||||
* @param array the array
|
||||
* @return the length of the array
|
||||
* @exception IllegalArgumentException if the object argument is not
|
||||
* an array
|
||||
*/
|
||||
public static native int getLength(Object array)
|
||||
throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Returns the value of the indexed component in the specified
|
||||
* array object. The value is automatically wrapped in an object
|
||||
* if it has a primitive type.
|
||||
*
|
||||
* @param array the array
|
||||
* @param index the index
|
||||
* @return the (possibly wrapped) value of the indexed component in
|
||||
* the specified array
|
||||
* @exception NullPointerException If the specified object is null
|
||||
* @exception IllegalArgumentException If the specified object is not
|
||||
* an array
|
||||
* @exception ArrayIndexOutOfBoundsException If the specified {@code index}
|
||||
* argument is negative, or if it is greater than or equal to the
|
||||
* length of the specified array
|
||||
*/
|
||||
public static native Object get(Object array, int index)
|
||||
throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
|
||||
|
||||
/**
|
||||
* Returns the value of the indexed component in the specified
|
||||
* array object, as a {@code boolean}.
|
||||
*
|
||||
* @param array the array
|
||||
* @param index the index
|
||||
* @return the value of the indexed component in the specified array
|
||||
* @exception NullPointerException If the specified object is null
|
||||
* @exception IllegalArgumentException If the specified object is not
|
||||
* an array, or if the indexed element cannot be converted to the
|
||||
* return type by an identity or widening conversion
|
||||
* @exception ArrayIndexOutOfBoundsException If the specified {@code index}
|
||||
* argument is negative, or if it is greater than or equal to the
|
||||
* length of the specified array
|
||||
* @see Array#get
|
||||
*/
|
||||
public static native boolean getBoolean(Object array, int index)
|
||||
throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
|
||||
|
||||
/**
|
||||
* Returns the value of the indexed component in the specified
|
||||
* array object, as a {@code byte}.
|
||||
*
|
||||
* @param array the array
|
||||
* @param index the index
|
||||
* @return the value of the indexed component in the specified array
|
||||
* @exception NullPointerException If the specified object is null
|
||||
* @exception IllegalArgumentException If the specified object is not
|
||||
* an array, or if the indexed element cannot be converted to the
|
||||
* return type by an identity or widening conversion
|
||||
* @exception ArrayIndexOutOfBoundsException If the specified {@code index}
|
||||
* argument is negative, or if it is greater than or equal to the
|
||||
* length of the specified array
|
||||
* @see Array#get
|
||||
*/
|
||||
public static native byte getByte(Object array, int index)
|
||||
throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
|
||||
|
||||
/**
|
||||
* Returns the value of the indexed component in the specified
|
||||
* array object, as a {@code char}.
|
||||
*
|
||||
* @param array the array
|
||||
* @param index the index
|
||||
* @return the value of the indexed component in the specified array
|
||||
* @exception NullPointerException If the specified object is null
|
||||
* @exception IllegalArgumentException If the specified object is not
|
||||
* an array, or if the indexed element cannot be converted to the
|
||||
* return type by an identity or widening conversion
|
||||
* @exception ArrayIndexOutOfBoundsException If the specified {@code index}
|
||||
* argument is negative, or if it is greater than or equal to the
|
||||
* length of the specified array
|
||||
* @see Array#get
|
||||
*/
|
||||
public static native char getChar(Object array, int index)
|
||||
throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
|
||||
|
||||
/**
|
||||
* Returns the value of the indexed component in the specified
|
||||
* array object, as a {@code short}.
|
||||
*
|
||||
* @param array the array
|
||||
* @param index the index
|
||||
* @return the value of the indexed component in the specified array
|
||||
* @exception NullPointerException If the specified object is null
|
||||
* @exception IllegalArgumentException If the specified object is not
|
||||
* an array, or if the indexed element cannot be converted to the
|
||||
* return type by an identity or widening conversion
|
||||
* @exception ArrayIndexOutOfBoundsException If the specified {@code index}
|
||||
* argument is negative, or if it is greater than or equal to the
|
||||
* length of the specified array
|
||||
* @see Array#get
|
||||
*/
|
||||
public static native short getShort(Object array, int index)
|
||||
throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
|
||||
|
||||
/**
|
||||
* Returns the value of the indexed component in the specified
|
||||
* array object, as an {@code int}.
|
||||
*
|
||||
* @param array the array
|
||||
* @param index the index
|
||||
* @return the value of the indexed component in the specified array
|
||||
* @exception NullPointerException If the specified object is null
|
||||
* @exception IllegalArgumentException If the specified object is not
|
||||
* an array, or if the indexed element cannot be converted to the
|
||||
* return type by an identity or widening conversion
|
||||
* @exception ArrayIndexOutOfBoundsException If the specified {@code index}
|
||||
* argument is negative, or if it is greater than or equal to the
|
||||
* length of the specified array
|
||||
* @see Array#get
|
||||
*/
|
||||
public static native int getInt(Object array, int index)
|
||||
throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
|
||||
|
||||
/**
|
||||
* Returns the value of the indexed component in the specified
|
||||
* array object, as a {@code long}.
|
||||
*
|
||||
* @param array the array
|
||||
* @param index the index
|
||||
* @return the value of the indexed component in the specified array
|
||||
* @exception NullPointerException If the specified object is null
|
||||
* @exception IllegalArgumentException If the specified object is not
|
||||
* an array, or if the indexed element cannot be converted to the
|
||||
* return type by an identity or widening conversion
|
||||
* @exception ArrayIndexOutOfBoundsException If the specified {@code index}
|
||||
* argument is negative, or if it is greater than or equal to the
|
||||
* length of the specified array
|
||||
* @see Array#get
|
||||
*/
|
||||
public static native long getLong(Object array, int index)
|
||||
throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
|
||||
|
||||
/**
|
||||
* Returns the value of the indexed component in the specified
|
||||
* array object, as a {@code float}.
|
||||
*
|
||||
* @param array the array
|
||||
* @param index the index
|
||||
* @return the value of the indexed component in the specified array
|
||||
* @exception NullPointerException If the specified object is null
|
||||
* @exception IllegalArgumentException If the specified object is not
|
||||
* an array, or if the indexed element cannot be converted to the
|
||||
* return type by an identity or widening conversion
|
||||
* @exception ArrayIndexOutOfBoundsException If the specified {@code index}
|
||||
* argument is negative, or if it is greater than or equal to the
|
||||
* length of the specified array
|
||||
* @see Array#get
|
||||
*/
|
||||
public static native float getFloat(Object array, int index)
|
||||
throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
|
||||
|
||||
/**
|
||||
* Returns the value of the indexed component in the specified
|
||||
* array object, as a {@code double}.
|
||||
*
|
||||
* @param array the array
|
||||
* @param index the index
|
||||
* @return the value of the indexed component in the specified array
|
||||
* @exception NullPointerException If the specified object is null
|
||||
* @exception IllegalArgumentException If the specified object is not
|
||||
* an array, or if the indexed element cannot be converted to the
|
||||
* return type by an identity or widening conversion
|
||||
* @exception ArrayIndexOutOfBoundsException If the specified {@code index}
|
||||
* argument is negative, or if it is greater than or equal to the
|
||||
* length of the specified array
|
||||
* @see Array#get
|
||||
*/
|
||||
public static native double getDouble(Object array, int index)
|
||||
throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
|
||||
|
||||
/**
|
||||
* Sets the value of the indexed component of the specified array
|
||||
* object to the specified new value. The new value is first
|
||||
* automatically unwrapped if the array has a primitive component
|
||||
* type.
|
||||
* @param array the array
|
||||
* @param index the index into the array
|
||||
* @param value the new value of the indexed component
|
||||
* @exception NullPointerException If the specified object argument
|
||||
* is null
|
||||
* @exception IllegalArgumentException If the specified object argument
|
||||
* is not an array, or if the array component type is primitive and
|
||||
* an unwrapping conversion fails
|
||||
* @exception ArrayIndexOutOfBoundsException If the specified {@code index}
|
||||
* argument is negative, or if it is greater than or equal to
|
||||
* the length of the specified array
|
||||
*/
|
||||
public static native void set(Object array, int index, Object value)
|
||||
throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
|
||||
|
||||
/**
|
||||
* Sets the value of the indexed component of the specified array
|
||||
* object to the specified {@code boolean} value.
|
||||
* @param array the array
|
||||
* @param index the index into the array
|
||||
* @param z the new value of the indexed component
|
||||
* @exception NullPointerException If the specified object argument
|
||||
* is null
|
||||
* @exception IllegalArgumentException If the specified object argument
|
||||
* is not an array, or if the specified value cannot be converted
|
||||
* to the underlying array's component type by an identity or a
|
||||
* primitive widening conversion
|
||||
* @exception ArrayIndexOutOfBoundsException If the specified {@code index}
|
||||
* argument is negative, or if it is greater than or equal to
|
||||
* the length of the specified array
|
||||
* @see Array#set
|
||||
*/
|
||||
public static native void setBoolean(Object array, int index, boolean z)
|
||||
throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
|
||||
|
||||
/**
|
||||
* Sets the value of the indexed component of the specified array
|
||||
* object to the specified {@code byte} value.
|
||||
* @param array the array
|
||||
* @param index the index into the array
|
||||
* @param b the new value of the indexed component
|
||||
* @exception NullPointerException If the specified object argument
|
||||
* is null
|
||||
* @exception IllegalArgumentException If the specified object argument
|
||||
* is not an array, or if the specified value cannot be converted
|
||||
* to the underlying array's component type by an identity or a
|
||||
* primitive widening conversion
|
||||
* @exception ArrayIndexOutOfBoundsException If the specified {@code index}
|
||||
* argument is negative, or if it is greater than or equal to
|
||||
* the length of the specified array
|
||||
* @see Array#set
|
||||
*/
|
||||
public static native void setByte(Object array, int index, byte b)
|
||||
throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
|
||||
|
||||
/**
|
||||
* Sets the value of the indexed component of the specified array
|
||||
* object to the specified {@code char} value.
|
||||
* @param array the array
|
||||
* @param index the index into the array
|
||||
* @param c the new value of the indexed component
|
||||
* @exception NullPointerException If the specified object argument
|
||||
* is null
|
||||
* @exception IllegalArgumentException If the specified object argument
|
||||
* is not an array, or if the specified value cannot be converted
|
||||
* to the underlying array's component type by an identity or a
|
||||
* primitive widening conversion
|
||||
* @exception ArrayIndexOutOfBoundsException If the specified {@code index}
|
||||
* argument is negative, or if it is greater than or equal to
|
||||
* the length of the specified array
|
||||
* @see Array#set
|
||||
*/
|
||||
public static native void setChar(Object array, int index, char c)
|
||||
throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
|
||||
|
||||
/**
|
||||
* Sets the value of the indexed component of the specified array
|
||||
* object to the specified {@code short} value.
|
||||
* @param array the array
|
||||
* @param index the index into the array
|
||||
* @param s the new value of the indexed component
|
||||
* @exception NullPointerException If the specified object argument
|
||||
* is null
|
||||
* @exception IllegalArgumentException If the specified object argument
|
||||
* is not an array, or if the specified value cannot be converted
|
||||
* to the underlying array's component type by an identity or a
|
||||
* primitive widening conversion
|
||||
* @exception ArrayIndexOutOfBoundsException If the specified {@code index}
|
||||
* argument is negative, or if it is greater than or equal to
|
||||
* the length of the specified array
|
||||
* @see Array#set
|
||||
*/
|
||||
public static native void setShort(Object array, int index, short s)
|
||||
throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
|
||||
|
||||
/**
|
||||
* Sets the value of the indexed component of the specified array
|
||||
* object to the specified {@code int} value.
|
||||
* @param array the array
|
||||
* @param index the index into the array
|
||||
* @param i the new value of the indexed component
|
||||
* @exception NullPointerException If the specified object argument
|
||||
* is null
|
||||
* @exception IllegalArgumentException If the specified object argument
|
||||
* is not an array, or if the specified value cannot be converted
|
||||
* to the underlying array's component type by an identity or a
|
||||
* primitive widening conversion
|
||||
* @exception ArrayIndexOutOfBoundsException If the specified {@code index}
|
||||
* argument is negative, or if it is greater than or equal to
|
||||
* the length of the specified array
|
||||
* @see Array#set
|
||||
*/
|
||||
public static native void setInt(Object array, int index, int i)
|
||||
throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
|
||||
|
||||
/**
|
||||
* Sets the value of the indexed component of the specified array
|
||||
* object to the specified {@code long} value.
|
||||
* @param array the array
|
||||
* @param index the index into the array
|
||||
* @param l the new value of the indexed component
|
||||
* @exception NullPointerException If the specified object argument
|
||||
* is null
|
||||
* @exception IllegalArgumentException If the specified object argument
|
||||
* is not an array, or if the specified value cannot be converted
|
||||
* to the underlying array's component type by an identity or a
|
||||
* primitive widening conversion
|
||||
* @exception ArrayIndexOutOfBoundsException If the specified {@code index}
|
||||
* argument is negative, or if it is greater than or equal to
|
||||
* the length of the specified array
|
||||
* @see Array#set
|
||||
*/
|
||||
public static native void setLong(Object array, int index, long l)
|
||||
throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
|
||||
|
||||
/**
|
||||
* Sets the value of the indexed component of the specified array
|
||||
* object to the specified {@code float} value.
|
||||
* @param array the array
|
||||
* @param index the index into the array
|
||||
* @param f the new value of the indexed component
|
||||
* @exception NullPointerException If the specified object argument
|
||||
* is null
|
||||
* @exception IllegalArgumentException If the specified object argument
|
||||
* is not an array, or if the specified value cannot be converted
|
||||
* to the underlying array's component type by an identity or a
|
||||
* primitive widening conversion
|
||||
* @exception ArrayIndexOutOfBoundsException If the specified {@code index}
|
||||
* argument is negative, or if it is greater than or equal to
|
||||
* the length of the specified array
|
||||
* @see Array#set
|
||||
*/
|
||||
public static native void setFloat(Object array, int index, float f)
|
||||
throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
|
||||
|
||||
/**
|
||||
* Sets the value of the indexed component of the specified array
|
||||
* object to the specified {@code double} value.
|
||||
* @param array the array
|
||||
* @param index the index into the array
|
||||
* @param d the new value of the indexed component
|
||||
* @exception NullPointerException If the specified object argument
|
||||
* is null
|
||||
* @exception IllegalArgumentException If the specified object argument
|
||||
* is not an array, or if the specified value cannot be converted
|
||||
* to the underlying array's component type by an identity or a
|
||||
* primitive widening conversion
|
||||
* @exception ArrayIndexOutOfBoundsException If the specified {@code index}
|
||||
* argument is negative, or if it is greater than or equal to
|
||||
* the length of the specified array
|
||||
* @see Array#set
|
||||
*/
|
||||
public static native void setDouble(Object array, int index, double d)
|
||||
throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
|
||||
|
||||
/*
|
||||
* Private
|
||||
*/
|
||||
|
||||
private static native Object newArray(Class<?> componentType, int length)
|
||||
throws NegativeArraySizeException;
|
||||
|
||||
private static native Object multiNewArray(Class<?> componentType,
|
||||
int[] dimensions)
|
||||
throws IllegalArgumentException, NegativeArraySizeException;
|
||||
|
||||
|
||||
}
|
||||
572
jdkSrc/jdk8/java/lang/reflect/Constructor.java
Normal file
572
jdkSrc/jdk8/java/lang/reflect/Constructor.java
Normal file
@@ -0,0 +1,572 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang.reflect;
|
||||
|
||||
import sun.reflect.CallerSensitive;
|
||||
import sun.reflect.ConstructorAccessor;
|
||||
import sun.reflect.Reflection;
|
||||
import sun.reflect.annotation.TypeAnnotation;
|
||||
import sun.reflect.annotation.TypeAnnotationParser;
|
||||
import sun.reflect.generics.repository.ConstructorRepository;
|
||||
import sun.reflect.generics.factory.CoreReflectionFactory;
|
||||
import sun.reflect.generics.factory.GenericsFactory;
|
||||
import sun.reflect.generics.scope.ConstructorScope;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.annotation.AnnotationFormatError;
|
||||
|
||||
/**
|
||||
* {@code Constructor} provides information about, and access to, a single
|
||||
* constructor for a class.
|
||||
*
|
||||
* <p>{@code Constructor} permits widening conversions to occur when matching the
|
||||
* actual parameters to newInstance() with the underlying
|
||||
* constructor's formal parameters, but throws an
|
||||
* {@code IllegalArgumentException} if a narrowing conversion would occur.
|
||||
*
|
||||
* @param <T> the class in which the constructor is declared
|
||||
*
|
||||
* @see Member
|
||||
* @see java.lang.Class
|
||||
* @see java.lang.Class#getConstructors()
|
||||
* @see java.lang.Class#getConstructor(Class[])
|
||||
* @see java.lang.Class#getDeclaredConstructors()
|
||||
*
|
||||
* @author Kenneth Russell
|
||||
* @author Nakul Saraiya
|
||||
*/
|
||||
public final class Constructor<T> extends Executable {
|
||||
private Class<T> clazz;
|
||||
private int slot;
|
||||
private Class<?>[] parameterTypes;
|
||||
private Class<?>[] exceptionTypes;
|
||||
private int modifiers;
|
||||
// Generics and annotations support
|
||||
private transient String signature;
|
||||
// generic info repository; lazily initialized
|
||||
private transient ConstructorRepository genericInfo;
|
||||
private byte[] annotations;
|
||||
private byte[] parameterAnnotations;
|
||||
|
||||
// Generics infrastructure
|
||||
// Accessor for factory
|
||||
private GenericsFactory getFactory() {
|
||||
// create scope and factory
|
||||
return CoreReflectionFactory.make(this, ConstructorScope.make(this));
|
||||
}
|
||||
|
||||
// Accessor for generic info repository
|
||||
@Override
|
||||
ConstructorRepository getGenericInfo() {
|
||||
// lazily initialize repository if necessary
|
||||
if (genericInfo == null) {
|
||||
// create and cache generic info repository
|
||||
genericInfo =
|
||||
ConstructorRepository.make(getSignature(),
|
||||
getFactory());
|
||||
}
|
||||
return genericInfo; //return cached repository
|
||||
}
|
||||
|
||||
private volatile ConstructorAccessor constructorAccessor;
|
||||
// For sharing of ConstructorAccessors. This branching structure
|
||||
// is currently only two levels deep (i.e., one root Constructor
|
||||
// and potentially many Constructor objects pointing to it.)
|
||||
//
|
||||
// If this branching structure would ever contain cycles, deadlocks can
|
||||
// occur in annotation code.
|
||||
private Constructor<T> root;
|
||||
|
||||
/**
|
||||
* Used by Excecutable for annotation sharing.
|
||||
*/
|
||||
@Override
|
||||
Executable getRoot() {
|
||||
return root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Package-private constructor used by ReflectAccess to enable
|
||||
* instantiation of these objects in Java code from the java.lang
|
||||
* package via sun.reflect.LangReflectAccess.
|
||||
*/
|
||||
Constructor(Class<T> declaringClass,
|
||||
Class<?>[] parameterTypes,
|
||||
Class<?>[] checkedExceptions,
|
||||
int modifiers,
|
||||
int slot,
|
||||
String signature,
|
||||
byte[] annotations,
|
||||
byte[] parameterAnnotations) {
|
||||
this.clazz = declaringClass;
|
||||
this.parameterTypes = parameterTypes;
|
||||
this.exceptionTypes = checkedExceptions;
|
||||
this.modifiers = modifiers;
|
||||
this.slot = slot;
|
||||
this.signature = signature;
|
||||
this.annotations = annotations;
|
||||
this.parameterAnnotations = parameterAnnotations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Package-private routine (exposed to java.lang.Class via
|
||||
* ReflectAccess) which returns a copy of this Constructor. The copy's
|
||||
* "root" field points to this Constructor.
|
||||
*/
|
||||
Constructor<T> copy() {
|
||||
// This routine enables sharing of ConstructorAccessor objects
|
||||
// among Constructor objects which refer to the same underlying
|
||||
// method in the VM. (All of this contortion is only necessary
|
||||
// because of the "accessibility" bit in AccessibleObject,
|
||||
// which implicitly requires that new java.lang.reflect
|
||||
// objects be fabricated for each reflective call on Class
|
||||
// objects.)
|
||||
if (this.root != null)
|
||||
throw new IllegalArgumentException("Can not copy a non-root Constructor");
|
||||
|
||||
Constructor<T> res = new Constructor<>(clazz,
|
||||
parameterTypes,
|
||||
exceptionTypes, modifiers, slot,
|
||||
signature,
|
||||
annotations,
|
||||
parameterAnnotations);
|
||||
res.root = this;
|
||||
// Might as well eagerly propagate this if already present
|
||||
res.constructorAccessor = constructorAccessor;
|
||||
return res;
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean hasGenericInformation() {
|
||||
return (getSignature() != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
byte[] getAnnotationBytes() {
|
||||
return annotations;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Class<T> getDeclaringClass() {
|
||||
return clazz;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this constructor, as a string. This is
|
||||
* the binary name of the constructor's declaring class.
|
||||
*/
|
||||
@Override
|
||||
public String getName() {
|
||||
return getDeclaringClass().getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public int getModifiers() {
|
||||
return modifiers;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @throws GenericSignatureFormatError {@inheritDoc}
|
||||
* @since 1.5
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public TypeVariable<Constructor<T>>[] getTypeParameters() {
|
||||
if (getSignature() != null) {
|
||||
return (TypeVariable<Constructor<T>>[])getGenericInfo().getTypeParameters();
|
||||
} else
|
||||
return (TypeVariable<Constructor<T>>[])new TypeVariable[0];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Class<?>[] getParameterTypes() {
|
||||
return parameterTypes.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 1.8
|
||||
*/
|
||||
public int getParameterCount() { return parameterTypes.length; }
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @throws GenericSignatureFormatError {@inheritDoc}
|
||||
* @throws TypeNotPresentException {@inheritDoc}
|
||||
* @throws MalformedParameterizedTypeException {@inheritDoc}
|
||||
* @since 1.5
|
||||
*/
|
||||
@Override
|
||||
public Type[] getGenericParameterTypes() {
|
||||
return super.getGenericParameterTypes();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Class<?>[] getExceptionTypes() {
|
||||
return exceptionTypes.clone();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @throws GenericSignatureFormatError {@inheritDoc}
|
||||
* @throws TypeNotPresentException {@inheritDoc}
|
||||
* @throws MalformedParameterizedTypeException {@inheritDoc}
|
||||
* @since 1.5
|
||||
*/
|
||||
@Override
|
||||
public Type[] getGenericExceptionTypes() {
|
||||
return super.getGenericExceptionTypes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this {@code Constructor} against the specified object.
|
||||
* Returns true if the objects are the same. Two {@code Constructor} objects are
|
||||
* the same if they were declared by the same class and have the
|
||||
* same formal parameter types.
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
if (obj != null && obj instanceof Constructor) {
|
||||
Constructor<?> other = (Constructor<?>)obj;
|
||||
if (getDeclaringClass() == other.getDeclaringClass()) {
|
||||
return equalParamTypes(parameterTypes, other.parameterTypes);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hashcode for this {@code Constructor}. The hashcode is
|
||||
* the same as the hashcode for the underlying constructor's
|
||||
* declaring class name.
|
||||
*/
|
||||
public int hashCode() {
|
||||
return getDeclaringClass().getName().hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string describing this {@code Constructor}. The string is
|
||||
* formatted as the constructor access modifiers, if any,
|
||||
* followed by the fully-qualified name of the declaring class,
|
||||
* followed by a parenthesized, comma-separated list of the
|
||||
* constructor's formal parameter types. For example:
|
||||
* <pre>
|
||||
* public java.util.Hashtable(int,float)
|
||||
* </pre>
|
||||
*
|
||||
* <p>The only possible modifiers for constructors are the access
|
||||
* modifiers {@code public}, {@code protected} or
|
||||
* {@code private}. Only one of these may appear, or none if the
|
||||
* constructor has default (package) access.
|
||||
*
|
||||
* @return a string describing this {@code Constructor}
|
||||
* @jls 8.8.3. Constructor Modifiers
|
||||
*/
|
||||
public String toString() {
|
||||
return sharedToString(Modifier.constructorModifiers(),
|
||||
false,
|
||||
parameterTypes,
|
||||
exceptionTypes);
|
||||
}
|
||||
|
||||
@Override
|
||||
void specificToStringHeader(StringBuilder sb) {
|
||||
sb.append(getDeclaringClass().getTypeName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string describing this {@code Constructor},
|
||||
* including type parameters. The string is formatted as the
|
||||
* constructor access modifiers, if any, followed by an
|
||||
* angle-bracketed comma separated list of the constructor's type
|
||||
* parameters, if any, followed by the fully-qualified name of the
|
||||
* declaring class, followed by a parenthesized, comma-separated
|
||||
* list of the constructor's generic formal parameter types.
|
||||
*
|
||||
* If this constructor was declared to take a variable number of
|
||||
* arguments, instead of denoting the last parameter as
|
||||
* "<tt><i>Type</i>[]</tt>", it is denoted as
|
||||
* "<tt><i>Type</i>...</tt>".
|
||||
*
|
||||
* A space is used to separate access modifiers from one another
|
||||
* and from the type parameters or return type. If there are no
|
||||
* type parameters, the type parameter list is elided; if the type
|
||||
* parameter list is present, a space separates the list from the
|
||||
* class name. If the constructor is declared to throw
|
||||
* exceptions, the parameter list is followed by a space, followed
|
||||
* by the word "{@code throws}" followed by a
|
||||
* comma-separated list of the thrown exception types.
|
||||
*
|
||||
* <p>The only possible modifiers for constructors are the access
|
||||
* modifiers {@code public}, {@code protected} or
|
||||
* {@code private}. Only one of these may appear, or none if the
|
||||
* constructor has default (package) access.
|
||||
*
|
||||
* @return a string describing this {@code Constructor},
|
||||
* include type parameters
|
||||
*
|
||||
* @since 1.5
|
||||
* @jls 8.8.3. Constructor Modifiers
|
||||
*/
|
||||
@Override
|
||||
public String toGenericString() {
|
||||
return sharedToGenericString(Modifier.constructorModifiers(), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
void specificToGenericStringHeader(StringBuilder sb) {
|
||||
specificToStringHeader(sb);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the constructor represented by this {@code Constructor} object to
|
||||
* create and initialize a new instance of the constructor's
|
||||
* declaring class, with the specified initialization parameters.
|
||||
* Individual parameters are automatically unwrapped to match
|
||||
* primitive formal parameters, and both primitive and reference
|
||||
* parameters are subject to method invocation conversions as necessary.
|
||||
*
|
||||
* <p>If the number of formal parameters required by the underlying constructor
|
||||
* is 0, the supplied {@code initargs} array may be of length 0 or null.
|
||||
*
|
||||
* <p>If the constructor's declaring class is an inner class in a
|
||||
* non-static context, the first argument to the constructor needs
|
||||
* to be the enclosing instance; see section 15.9.3 of
|
||||
* <cite>The Java™ Language Specification</cite>.
|
||||
*
|
||||
* <p>If the required access and argument checks succeed and the
|
||||
* instantiation will proceed, the constructor's declaring class
|
||||
* is initialized if it has not already been initialized.
|
||||
*
|
||||
* <p>If the constructor completes normally, returns the newly
|
||||
* created and initialized instance.
|
||||
*
|
||||
* @param initargs array of objects to be passed as arguments to
|
||||
* the constructor call; values of primitive types are wrapped in
|
||||
* a wrapper object of the appropriate type (e.g. a {@code float}
|
||||
* in a {@link java.lang.Float Float})
|
||||
*
|
||||
* @return a new object created by calling the constructor
|
||||
* this object represents
|
||||
*
|
||||
* @exception IllegalAccessException if this {@code Constructor} object
|
||||
* is enforcing Java language access control and the underlying
|
||||
* constructor is inaccessible.
|
||||
* @exception IllegalArgumentException if the number of actual
|
||||
* and formal parameters differ; if an unwrapping
|
||||
* conversion for primitive arguments fails; or if,
|
||||
* after possible unwrapping, a parameter value
|
||||
* cannot be converted to the corresponding formal
|
||||
* parameter type by a method invocation conversion; if
|
||||
* this constructor pertains to an enum type.
|
||||
* @exception InstantiationException if the class that declares the
|
||||
* underlying constructor represents an abstract class.
|
||||
* @exception InvocationTargetException if the underlying constructor
|
||||
* throws an exception.
|
||||
* @exception ExceptionInInitializerError if the initialization provoked
|
||||
* by this method fails.
|
||||
*/
|
||||
@CallerSensitive
|
||||
public T newInstance(Object ... initargs)
|
||||
throws InstantiationException, IllegalAccessException,
|
||||
IllegalArgumentException, InvocationTargetException
|
||||
{
|
||||
if (!override) {
|
||||
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
checkAccess(caller, clazz, null, modifiers);
|
||||
}
|
||||
}
|
||||
if ((clazz.getModifiers() & Modifier.ENUM) != 0)
|
||||
throw new IllegalArgumentException("Cannot reflectively create enum objects");
|
||||
ConstructorAccessor ca = constructorAccessor; // read volatile
|
||||
if (ca == null) {
|
||||
ca = acquireConstructorAccessor();
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
T inst = (T) ca.newInstance(initargs);
|
||||
return inst;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 1.5
|
||||
*/
|
||||
@Override
|
||||
public boolean isVarArgs() {
|
||||
return super.isVarArgs();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @jls 13.1 The Form of a Binary
|
||||
* @since 1.5
|
||||
*/
|
||||
@Override
|
||||
public boolean isSynthetic() {
|
||||
return super.isSynthetic();
|
||||
}
|
||||
|
||||
// NOTE that there is no synchronization used here. It is correct
|
||||
// (though not efficient) to generate more than one
|
||||
// ConstructorAccessor for a given Constructor. However, avoiding
|
||||
// synchronization will probably make the implementation more
|
||||
// scalable.
|
||||
private ConstructorAccessor acquireConstructorAccessor() {
|
||||
// First check to see if one has been created yet, and take it
|
||||
// if so.
|
||||
ConstructorAccessor tmp = null;
|
||||
if (root != null) tmp = root.getConstructorAccessor();
|
||||
if (tmp != null) {
|
||||
constructorAccessor = tmp;
|
||||
} else {
|
||||
// Otherwise fabricate one and propagate it up to the root
|
||||
tmp = reflectionFactory.newConstructorAccessor(this);
|
||||
setConstructorAccessor(tmp);
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// Returns ConstructorAccessor for this Constructor object, not
|
||||
// looking up the chain to the root
|
||||
ConstructorAccessor getConstructorAccessor() {
|
||||
return constructorAccessor;
|
||||
}
|
||||
|
||||
// Sets the ConstructorAccessor for this Constructor object and
|
||||
// (recursively) its root
|
||||
void setConstructorAccessor(ConstructorAccessor accessor) {
|
||||
constructorAccessor = accessor;
|
||||
// Propagate up
|
||||
if (root != null) {
|
||||
root.setConstructorAccessor(accessor);
|
||||
}
|
||||
}
|
||||
|
||||
int getSlot() {
|
||||
return slot;
|
||||
}
|
||||
|
||||
String getSignature() {
|
||||
return signature;
|
||||
}
|
||||
|
||||
byte[] getRawAnnotations() {
|
||||
return annotations;
|
||||
}
|
||||
|
||||
byte[] getRawParameterAnnotations() {
|
||||
return parameterAnnotations;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
* @since 1.5
|
||||
*/
|
||||
public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
|
||||
return super.getAnnotation(annotationClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 1.5
|
||||
*/
|
||||
public Annotation[] getDeclaredAnnotations() {
|
||||
return super.getDeclaredAnnotations();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 1.5
|
||||
*/
|
||||
@Override
|
||||
public Annotation[][] getParameterAnnotations() {
|
||||
return sharedGetParameterAnnotations(parameterTypes, parameterAnnotations);
|
||||
}
|
||||
|
||||
@Override
|
||||
void handleParameterNumberMismatch(int resultLength, int numParameters) {
|
||||
Class<?> declaringClass = getDeclaringClass();
|
||||
if (declaringClass.isEnum() ||
|
||||
declaringClass.isAnonymousClass() ||
|
||||
declaringClass.isLocalClass() )
|
||||
return ; // Can't do reliable parameter counting
|
||||
else {
|
||||
if (!declaringClass.isMemberClass() || // top-level
|
||||
// Check for the enclosing instance parameter for
|
||||
// non-static member classes
|
||||
(declaringClass.isMemberClass() &&
|
||||
((declaringClass.getModifiers() & Modifier.STATIC) == 0) &&
|
||||
resultLength + 1 != numParameters) ) {
|
||||
throw new AnnotationFormatError(
|
||||
"Parameter annotations don't match number of parameters");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 1.8
|
||||
*/
|
||||
@Override
|
||||
public AnnotatedType getAnnotatedReturnType() {
|
||||
return getAnnotatedReturnType0(getDeclaringClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 1.8
|
||||
*/
|
||||
@Override
|
||||
public AnnotatedType getAnnotatedReceiverType() {
|
||||
if (getDeclaringClass().getEnclosingClass() == null)
|
||||
return super.getAnnotatedReceiverType();
|
||||
|
||||
return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes0(),
|
||||
sun.misc.SharedSecrets.getJavaLangAccess().
|
||||
getConstantPool(getDeclaringClass()),
|
||||
this,
|
||||
getDeclaringClass(),
|
||||
getDeclaringClass().getEnclosingClass(),
|
||||
TypeAnnotation.TypeAnnotationTarget.METHOD_RECEIVER);
|
||||
}
|
||||
}
|
||||
728
jdkSrc/jdk8/java/lang/reflect/Executable.java
Normal file
728
jdkSrc/jdk8/java/lang/reflect/Executable.java
Normal file
@@ -0,0 +1,728 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang.reflect;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import sun.reflect.annotation.AnnotationParser;
|
||||
import sun.reflect.annotation.AnnotationSupport;
|
||||
import sun.reflect.annotation.TypeAnnotationParser;
|
||||
import sun.reflect.annotation.TypeAnnotation;
|
||||
import sun.reflect.generics.repository.ConstructorRepository;
|
||||
|
||||
/**
|
||||
* A shared superclass for the common functionality of {@link Method}
|
||||
* and {@link Constructor}.
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
public abstract class Executable extends AccessibleObject
|
||||
implements Member, GenericDeclaration {
|
||||
/*
|
||||
* Only grant package-visibility to the constructor.
|
||||
*/
|
||||
Executable() {}
|
||||
|
||||
/**
|
||||
* Accessor method to allow code sharing
|
||||
*/
|
||||
abstract byte[] getAnnotationBytes();
|
||||
|
||||
/**
|
||||
* Accessor method to allow code sharing
|
||||
*/
|
||||
abstract Executable getRoot();
|
||||
|
||||
/**
|
||||
* Does the Executable have generic information.
|
||||
*/
|
||||
abstract boolean hasGenericInformation();
|
||||
|
||||
abstract ConstructorRepository getGenericInfo();
|
||||
|
||||
boolean equalParamTypes(Class<?>[] params1, Class<?>[] params2) {
|
||||
/* Avoid unnecessary cloning */
|
||||
if (params1.length == params2.length) {
|
||||
for (int i = 0; i < params1.length; i++) {
|
||||
if (params1[i] != params2[i])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Annotation[][] parseParameterAnnotations(byte[] parameterAnnotations) {
|
||||
return AnnotationParser.parseParameterAnnotations(
|
||||
parameterAnnotations,
|
||||
sun.misc.SharedSecrets.getJavaLangAccess().
|
||||
getConstantPool(getDeclaringClass()),
|
||||
getDeclaringClass());
|
||||
}
|
||||
|
||||
void separateWithCommas(Class<?>[] types, StringBuilder sb) {
|
||||
for (int j = 0; j < types.length; j++) {
|
||||
sb.append(types[j].getTypeName());
|
||||
if (j < (types.length - 1))
|
||||
sb.append(",");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void printModifiersIfNonzero(StringBuilder sb, int mask, boolean isDefault) {
|
||||
int mod = getModifiers() & mask;
|
||||
|
||||
if (mod != 0 && !isDefault) {
|
||||
sb.append(Modifier.toString(mod)).append(' ');
|
||||
} else {
|
||||
int access_mod = mod & Modifier.ACCESS_MODIFIERS;
|
||||
if (access_mod != 0)
|
||||
sb.append(Modifier.toString(access_mod)).append(' ');
|
||||
if (isDefault)
|
||||
sb.append("default ");
|
||||
mod = (mod & ~Modifier.ACCESS_MODIFIERS);
|
||||
if (mod != 0)
|
||||
sb.append(Modifier.toString(mod)).append(' ');
|
||||
}
|
||||
}
|
||||
|
||||
String sharedToString(int modifierMask,
|
||||
boolean isDefault,
|
||||
Class<?>[] parameterTypes,
|
||||
Class<?>[] exceptionTypes) {
|
||||
try {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
printModifiersIfNonzero(sb, modifierMask, isDefault);
|
||||
specificToStringHeader(sb);
|
||||
|
||||
sb.append('(');
|
||||
separateWithCommas(parameterTypes, sb);
|
||||
sb.append(')');
|
||||
if (exceptionTypes.length > 0) {
|
||||
sb.append(" throws ");
|
||||
separateWithCommas(exceptionTypes, sb);
|
||||
}
|
||||
return sb.toString();
|
||||
} catch (Exception e) {
|
||||
return "<" + e + ">";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate toString header information specific to a method or
|
||||
* constructor.
|
||||
*/
|
||||
abstract void specificToStringHeader(StringBuilder sb);
|
||||
|
||||
String sharedToGenericString(int modifierMask, boolean isDefault) {
|
||||
try {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
printModifiersIfNonzero(sb, modifierMask, isDefault);
|
||||
|
||||
TypeVariable<?>[] typeparms = getTypeParameters();
|
||||
if (typeparms.length > 0) {
|
||||
boolean first = true;
|
||||
sb.append('<');
|
||||
for(TypeVariable<?> typeparm: typeparms) {
|
||||
if (!first)
|
||||
sb.append(',');
|
||||
// Class objects can't occur here; no need to test
|
||||
// and call Class.getName().
|
||||
sb.append(typeparm.toString());
|
||||
first = false;
|
||||
}
|
||||
sb.append("> ");
|
||||
}
|
||||
|
||||
specificToGenericStringHeader(sb);
|
||||
|
||||
sb.append('(');
|
||||
Type[] params = getGenericParameterTypes();
|
||||
for (int j = 0; j < params.length; j++) {
|
||||
String param = params[j].getTypeName();
|
||||
if (isVarArgs() && (j == params.length - 1)) // replace T[] with T...
|
||||
param = param.replaceFirst("\\[\\]$", "...");
|
||||
sb.append(param);
|
||||
if (j < (params.length - 1))
|
||||
sb.append(',');
|
||||
}
|
||||
sb.append(')');
|
||||
Type[] exceptions = getGenericExceptionTypes();
|
||||
if (exceptions.length > 0) {
|
||||
sb.append(" throws ");
|
||||
for (int k = 0; k < exceptions.length; k++) {
|
||||
sb.append((exceptions[k] instanceof Class)?
|
||||
((Class)exceptions[k]).getName():
|
||||
exceptions[k].toString());
|
||||
if (k < (exceptions.length - 1))
|
||||
sb.append(',');
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
} catch (Exception e) {
|
||||
return "<" + e + ">";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate toGenericString header information specific to a
|
||||
* method or constructor.
|
||||
*/
|
||||
abstract void specificToGenericStringHeader(StringBuilder sb);
|
||||
|
||||
/**
|
||||
* Returns the {@code Class} object representing the class or interface
|
||||
* that declares the executable represented by this object.
|
||||
*/
|
||||
public abstract Class<?> getDeclaringClass();
|
||||
|
||||
/**
|
||||
* Returns the name of the executable represented by this object.
|
||||
*/
|
||||
public abstract String getName();
|
||||
|
||||
/**
|
||||
* Returns the Java language {@linkplain Modifier modifiers} for
|
||||
* the executable represented by this object.
|
||||
*/
|
||||
public abstract int getModifiers();
|
||||
|
||||
/**
|
||||
* Returns an array of {@code TypeVariable} objects that represent the
|
||||
* type variables declared by the generic declaration represented by this
|
||||
* {@code GenericDeclaration} object, in declaration order. Returns an
|
||||
* array of length 0 if the underlying generic declaration declares no type
|
||||
* variables.
|
||||
*
|
||||
* @return an array of {@code TypeVariable} objects that represent
|
||||
* the type variables declared by this generic declaration
|
||||
* @throws GenericSignatureFormatError if the generic
|
||||
* signature of this generic declaration does not conform to
|
||||
* the format specified in
|
||||
* <cite>The Java™ Virtual Machine Specification</cite>
|
||||
*/
|
||||
public abstract TypeVariable<?>[] getTypeParameters();
|
||||
|
||||
/**
|
||||
* Returns an array of {@code Class} objects that represent the formal
|
||||
* parameter types, in declaration order, of the executable
|
||||
* represented by this object. Returns an array of length
|
||||
* 0 if the underlying executable takes no parameters.
|
||||
*
|
||||
* @return the parameter types for the executable this object
|
||||
* represents
|
||||
*/
|
||||
public abstract Class<?>[] getParameterTypes();
|
||||
|
||||
/**
|
||||
* Returns the number of formal parameters (whether explicitly
|
||||
* declared or implicitly declared or neither) for the executable
|
||||
* represented by this object.
|
||||
*
|
||||
* @return The number of formal parameters for the executable this
|
||||
* object represents
|
||||
*/
|
||||
public int getParameterCount() {
|
||||
throw new AbstractMethodError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of {@code Type} objects that represent the formal
|
||||
* parameter types, in declaration order, of the executable represented by
|
||||
* this object. Returns an array of length 0 if the
|
||||
* underlying executable takes no parameters.
|
||||
*
|
||||
* <p>If a formal parameter type is a parameterized type,
|
||||
* the {@code Type} object returned for it must accurately reflect
|
||||
* the actual type parameters used in the source code.
|
||||
*
|
||||
* <p>If a formal parameter type is a type variable or a parameterized
|
||||
* type, it is created. Otherwise, it is resolved.
|
||||
*
|
||||
* @return an array of {@code Type}s that represent the formal
|
||||
* parameter types of the underlying executable, in declaration order
|
||||
* @throws GenericSignatureFormatError
|
||||
* if the generic method signature does not conform to the format
|
||||
* specified in
|
||||
* <cite>The Java™ Virtual Machine Specification</cite>
|
||||
* @throws TypeNotPresentException if any of the parameter
|
||||
* types of the underlying executable refers to a non-existent type
|
||||
* declaration
|
||||
* @throws MalformedParameterizedTypeException if any of
|
||||
* the underlying executable's parameter types refer to a parameterized
|
||||
* type that cannot be instantiated for any reason
|
||||
*/
|
||||
public Type[] getGenericParameterTypes() {
|
||||
if (hasGenericInformation())
|
||||
return getGenericInfo().getParameterTypes();
|
||||
else
|
||||
return getParameterTypes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Behaves like {@code getGenericParameterTypes}, but returns type
|
||||
* information for all parameters, including synthetic parameters.
|
||||
*/
|
||||
Type[] getAllGenericParameterTypes() {
|
||||
final boolean genericInfo = hasGenericInformation();
|
||||
|
||||
// Easy case: we don't have generic parameter information. In
|
||||
// this case, we just return the result of
|
||||
// getParameterTypes().
|
||||
if (!genericInfo) {
|
||||
return getParameterTypes();
|
||||
} else {
|
||||
final boolean realParamData = hasRealParameterData();
|
||||
final Type[] genericParamTypes = getGenericParameterTypes();
|
||||
final Type[] nonGenericParamTypes = getParameterTypes();
|
||||
final Type[] out = new Type[nonGenericParamTypes.length];
|
||||
final Parameter[] params = getParameters();
|
||||
int fromidx = 0;
|
||||
// If we have real parameter data, then we use the
|
||||
// synthetic and mandate flags to our advantage.
|
||||
if (realParamData) {
|
||||
for (int i = 0; i < out.length; i++) {
|
||||
final Parameter param = params[i];
|
||||
if (param.isSynthetic() || param.isImplicit()) {
|
||||
// If we hit a synthetic or mandated parameter,
|
||||
// use the non generic parameter info.
|
||||
out[i] = nonGenericParamTypes[i];
|
||||
} else {
|
||||
// Otherwise, use the generic parameter info.
|
||||
out[i] = genericParamTypes[fromidx];
|
||||
fromidx++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Otherwise, use the non-generic parameter data.
|
||||
// Without method parameter reflection data, we have
|
||||
// no way to figure out which parameters are
|
||||
// synthetic/mandated, thus, no way to match up the
|
||||
// indexes.
|
||||
return genericParamTypes.length == nonGenericParamTypes.length ?
|
||||
genericParamTypes : nonGenericParamTypes;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of {@code Parameter} objects that represent
|
||||
* all the parameters to the underlying executable represented by
|
||||
* this object. Returns an array of length 0 if the executable
|
||||
* has no parameters.
|
||||
*
|
||||
* <p>The parameters of the underlying executable do not necessarily
|
||||
* have unique names, or names that are legal identifiers in the
|
||||
* Java programming language (JLS 3.8).
|
||||
*
|
||||
* @throws MalformedParametersException if the class file contains
|
||||
* a MethodParameters attribute that is improperly formatted.
|
||||
* @return an array of {@code Parameter} objects representing all
|
||||
* the parameters to the executable this object represents.
|
||||
*/
|
||||
public Parameter[] getParameters() {
|
||||
// TODO: This may eventually need to be guarded by security
|
||||
// mechanisms similar to those in Field, Method, etc.
|
||||
//
|
||||
// Need to copy the cached array to prevent users from messing
|
||||
// with it. Since parameters are immutable, we can
|
||||
// shallow-copy.
|
||||
return privateGetParameters().clone();
|
||||
}
|
||||
|
||||
private Parameter[] synthesizeAllParams() {
|
||||
final int realparams = getParameterCount();
|
||||
final Parameter[] out = new Parameter[realparams];
|
||||
for (int i = 0; i < realparams; i++)
|
||||
// TODO: is there a way to synthetically derive the
|
||||
// modifiers? Probably not in the general case, since
|
||||
// we'd have no way of knowing about them, but there
|
||||
// may be specific cases.
|
||||
out[i] = new Parameter("arg" + i, 0, this, i);
|
||||
return out;
|
||||
}
|
||||
|
||||
private void verifyParameters(final Parameter[] parameters) {
|
||||
final int mask = Modifier.FINAL | Modifier.SYNTHETIC | Modifier.MANDATED;
|
||||
|
||||
if (getParameterTypes().length != parameters.length)
|
||||
throw new MalformedParametersException("Wrong number of parameters in MethodParameters attribute");
|
||||
|
||||
for (Parameter parameter : parameters) {
|
||||
final String name = parameter.getRealName();
|
||||
final int mods = parameter.getModifiers();
|
||||
|
||||
if (name != null) {
|
||||
if (name.isEmpty() || name.indexOf('.') != -1 ||
|
||||
name.indexOf(';') != -1 || name.indexOf('[') != -1 ||
|
||||
name.indexOf('/') != -1) {
|
||||
throw new MalformedParametersException("Invalid parameter name \"" + name + "\"");
|
||||
}
|
||||
}
|
||||
|
||||
if (mods != (mods & mask)) {
|
||||
throw new MalformedParametersException("Invalid parameter modifiers");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Parameter[] privateGetParameters() {
|
||||
// Use tmp to avoid multiple writes to a volatile.
|
||||
Parameter[] tmp = parameters;
|
||||
|
||||
if (tmp == null) {
|
||||
|
||||
// Otherwise, go to the JVM to get them
|
||||
try {
|
||||
tmp = getParameters0();
|
||||
} catch(IllegalArgumentException e) {
|
||||
// Rethrow ClassFormatErrors
|
||||
throw new MalformedParametersException("Invalid constant pool index");
|
||||
}
|
||||
|
||||
// If we get back nothing, then synthesize parameters
|
||||
if (tmp == null) {
|
||||
hasRealParameterData = false;
|
||||
tmp = synthesizeAllParams();
|
||||
} else {
|
||||
hasRealParameterData = true;
|
||||
verifyParameters(tmp);
|
||||
}
|
||||
|
||||
parameters = tmp;
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
boolean hasRealParameterData() {
|
||||
// If this somehow gets called before parameters gets
|
||||
// initialized, force it into existence.
|
||||
if (parameters == null) {
|
||||
privateGetParameters();
|
||||
}
|
||||
return hasRealParameterData;
|
||||
}
|
||||
|
||||
private transient volatile boolean hasRealParameterData;
|
||||
private transient volatile Parameter[] parameters;
|
||||
|
||||
private native Parameter[] getParameters0();
|
||||
native byte[] getTypeAnnotationBytes0();
|
||||
|
||||
// Needed by reflectaccess
|
||||
byte[] getTypeAnnotationBytes() {
|
||||
return getTypeAnnotationBytes0();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of {@code Class} objects that represent the
|
||||
* types of exceptions declared to be thrown by the underlying
|
||||
* executable represented by this object. Returns an array of
|
||||
* length 0 if the executable declares no exceptions in its {@code
|
||||
* throws} clause.
|
||||
*
|
||||
* @return the exception types declared as being thrown by the
|
||||
* executable this object represents
|
||||
*/
|
||||
public abstract Class<?>[] getExceptionTypes();
|
||||
|
||||
/**
|
||||
* Returns an array of {@code Type} objects that represent the
|
||||
* exceptions declared to be thrown by this executable object.
|
||||
* Returns an array of length 0 if the underlying executable declares
|
||||
* no exceptions in its {@code throws} clause.
|
||||
*
|
||||
* <p>If an exception type is a type variable or a parameterized
|
||||
* type, it is created. Otherwise, it is resolved.
|
||||
*
|
||||
* @return an array of Types that represent the exception types
|
||||
* thrown by the underlying executable
|
||||
* @throws GenericSignatureFormatError
|
||||
* if the generic method signature does not conform to the format
|
||||
* specified in
|
||||
* <cite>The Java™ Virtual Machine Specification</cite>
|
||||
* @throws TypeNotPresentException if the underlying executable's
|
||||
* {@code throws} clause refers to a non-existent type declaration
|
||||
* @throws MalformedParameterizedTypeException if
|
||||
* the underlying executable's {@code throws} clause refers to a
|
||||
* parameterized type that cannot be instantiated for any reason
|
||||
*/
|
||||
public Type[] getGenericExceptionTypes() {
|
||||
Type[] result;
|
||||
if (hasGenericInformation() &&
|
||||
((result = getGenericInfo().getExceptionTypes()).length > 0))
|
||||
return result;
|
||||
else
|
||||
return getExceptionTypes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string describing this {@code Executable}, including
|
||||
* any type parameters.
|
||||
* @return a string describing this {@code Executable}, including
|
||||
* any type parameters
|
||||
*/
|
||||
public abstract String toGenericString();
|
||||
|
||||
/**
|
||||
* Returns {@code true} if this executable was declared to take a
|
||||
* variable number of arguments; returns {@code false} otherwise.
|
||||
*
|
||||
* @return {@code true} if an only if this executable was declared
|
||||
* to take a variable number of arguments.
|
||||
*/
|
||||
public boolean isVarArgs() {
|
||||
return (getModifiers() & Modifier.VARARGS) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if this executable is a synthetic
|
||||
* construct; returns {@code false} otherwise.
|
||||
*
|
||||
* @return true if and only if this executable is a synthetic
|
||||
* construct as defined by
|
||||
* <cite>The Java™ Language Specification</cite>.
|
||||
* @jls 13.1 The Form of a Binary
|
||||
*/
|
||||
public boolean isSynthetic() {
|
||||
return Modifier.isSynthetic(getModifiers());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of arrays of {@code Annotation}s that
|
||||
* represent the annotations on the formal parameters, in
|
||||
* declaration order, of the {@code Executable} represented by
|
||||
* this object. Synthetic and mandated parameters (see
|
||||
* explanation below), such as the outer "this" parameter to an
|
||||
* inner class constructor will be represented in the returned
|
||||
* array. If the executable has no parameters (meaning no formal,
|
||||
* no synthetic, and no mandated parameters), a zero-length array
|
||||
* will be returned. If the {@code Executable} has one or more
|
||||
* parameters, a nested array of length zero is returned for each
|
||||
* parameter with no annotations. The annotation objects contained
|
||||
* in the returned arrays are serializable. The caller of this
|
||||
* method is free to modify the returned arrays; it will have no
|
||||
* effect on the arrays returned to other callers.
|
||||
*
|
||||
* A compiler may add extra parameters that are implicitly
|
||||
* declared in source ("mandated"), as well as parameters that
|
||||
* are neither implicitly nor explicitly declared in source
|
||||
* ("synthetic") to the parameter list for a method. See {@link
|
||||
* java.lang.reflect.Parameter} for more information.
|
||||
*
|
||||
* @see java.lang.reflect.Parameter
|
||||
* @see java.lang.reflect.Parameter#getAnnotations
|
||||
* @return an array of arrays that represent the annotations on
|
||||
* the formal and implicit parameters, in declaration order, of
|
||||
* the executable represented by this object
|
||||
*/
|
||||
public abstract Annotation[][] getParameterAnnotations();
|
||||
|
||||
Annotation[][] sharedGetParameterAnnotations(Class<?>[] parameterTypes,
|
||||
byte[] parameterAnnotations) {
|
||||
int numParameters = parameterTypes.length;
|
||||
if (parameterAnnotations == null)
|
||||
return new Annotation[numParameters][0];
|
||||
|
||||
Annotation[][] result = parseParameterAnnotations(parameterAnnotations);
|
||||
|
||||
if (result.length != numParameters)
|
||||
handleParameterNumberMismatch(result.length, numParameters);
|
||||
return result;
|
||||
}
|
||||
|
||||
abstract void handleParameterNumberMismatch(int resultLength, int numParameters);
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
*/
|
||||
public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
|
||||
Objects.requireNonNull(annotationClass);
|
||||
return annotationClass.cast(declaredAnnotations().get(annotationClass));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
|
||||
Objects.requireNonNull(annotationClass);
|
||||
|
||||
return AnnotationSupport.getDirectlyAndIndirectlyPresent(declaredAnnotations(), annotationClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public Annotation[] getDeclaredAnnotations() {
|
||||
return AnnotationParser.toArray(declaredAnnotations());
|
||||
}
|
||||
|
||||
private transient volatile Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
|
||||
|
||||
private Map<Class<? extends Annotation>, Annotation> declaredAnnotations() {
|
||||
Map<Class<? extends Annotation>, Annotation> declAnnos;
|
||||
if ((declAnnos = declaredAnnotations) == null) {
|
||||
synchronized (this) {
|
||||
if ((declAnnos = declaredAnnotations) == null) {
|
||||
Executable root = getRoot();
|
||||
if (root != null) {
|
||||
declAnnos = root.declaredAnnotations();
|
||||
} else {
|
||||
declAnnos = AnnotationParser.parseAnnotations(
|
||||
getAnnotationBytes(),
|
||||
sun.misc.SharedSecrets.getJavaLangAccess().
|
||||
getConstantPool(getDeclaringClass()),
|
||||
getDeclaringClass()
|
||||
);
|
||||
}
|
||||
declaredAnnotations = declAnnos;
|
||||
}
|
||||
}
|
||||
}
|
||||
return declAnnos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an {@code AnnotatedType} object that represents the use of a type to
|
||||
* specify the return type of the method/constructor represented by this
|
||||
* Executable.
|
||||
*
|
||||
* If this {@code Executable} object represents a constructor, the {@code
|
||||
* AnnotatedType} object represents the type of the constructed object.
|
||||
*
|
||||
* If this {@code Executable} object represents a method, the {@code
|
||||
* AnnotatedType} object represents the use of a type to specify the return
|
||||
* type of the method.
|
||||
*
|
||||
* @return an object representing the return type of the method
|
||||
* or constructor represented by this {@code Executable}
|
||||
*/
|
||||
public abstract AnnotatedType getAnnotatedReturnType();
|
||||
|
||||
/* Helper for subclasses of Executable.
|
||||
*
|
||||
* Returns an AnnotatedType object that represents the use of a type to
|
||||
* specify the return type of the method/constructor represented by this
|
||||
* Executable.
|
||||
*/
|
||||
AnnotatedType getAnnotatedReturnType0(Type returnType) {
|
||||
return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes0(),
|
||||
sun.misc.SharedSecrets.getJavaLangAccess().
|
||||
getConstantPool(getDeclaringClass()),
|
||||
this,
|
||||
getDeclaringClass(),
|
||||
returnType,
|
||||
TypeAnnotation.TypeAnnotationTarget.METHOD_RETURN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an {@code AnnotatedType} object that represents the use of a
|
||||
* type to specify the receiver type of the method/constructor represented
|
||||
* by this Executable object. The receiver type of a method/constructor is
|
||||
* available only if the method/constructor has a <em>receiver
|
||||
* parameter</em> (JLS 8.4.1).
|
||||
*
|
||||
* If this {@code Executable} object represents a constructor or instance
|
||||
* method that does not have a receiver parameter, or has a receiver
|
||||
* parameter with no annotations on its type, then the return value is an
|
||||
* {@code AnnotatedType} object representing an element with no
|
||||
* annotations.
|
||||
*
|
||||
* If this {@code Executable} object represents a static method, then the
|
||||
* return value is null.
|
||||
*
|
||||
* @return an object representing the receiver type of the method or
|
||||
* constructor represented by this {@code Executable}
|
||||
*/
|
||||
public AnnotatedType getAnnotatedReceiverType() {
|
||||
if (Modifier.isStatic(this.getModifiers()))
|
||||
return null;
|
||||
return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes0(),
|
||||
sun.misc.SharedSecrets.getJavaLangAccess().
|
||||
getConstantPool(getDeclaringClass()),
|
||||
this,
|
||||
getDeclaringClass(),
|
||||
getDeclaringClass(),
|
||||
TypeAnnotation.TypeAnnotationTarget.METHOD_RECEIVER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of {@code AnnotatedType} objects that represent the use
|
||||
* of types to specify formal parameter types of the method/constructor
|
||||
* represented by this Executable. The order of the objects in the array
|
||||
* corresponds to the order of the formal parameter types in the
|
||||
* declaration of the method/constructor.
|
||||
*
|
||||
* Returns an array of length 0 if the method/constructor declares no
|
||||
* parameters.
|
||||
*
|
||||
* @return an array of objects representing the types of the
|
||||
* formal parameters of the method or constructor represented by this
|
||||
* {@code Executable}
|
||||
*/
|
||||
public AnnotatedType[] getAnnotatedParameterTypes() {
|
||||
return TypeAnnotationParser.buildAnnotatedTypes(getTypeAnnotationBytes0(),
|
||||
sun.misc.SharedSecrets.getJavaLangAccess().
|
||||
getConstantPool(getDeclaringClass()),
|
||||
this,
|
||||
getDeclaringClass(),
|
||||
getAllGenericParameterTypes(),
|
||||
TypeAnnotation.TypeAnnotationTarget.METHOD_FORMAL_PARAMETER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of {@code AnnotatedType} objects that represent the use
|
||||
* of types to specify the declared exceptions of the method/constructor
|
||||
* represented by this Executable. The order of the objects in the array
|
||||
* corresponds to the order of the exception types in the declaration of
|
||||
* the method/constructor.
|
||||
*
|
||||
* Returns an array of length 0 if the method/constructor declares no
|
||||
* exceptions.
|
||||
*
|
||||
* @return an array of objects representing the declared
|
||||
* exceptions of the method or constructor represented by this {@code
|
||||
* Executable}
|
||||
*/
|
||||
public AnnotatedType[] getAnnotatedExceptionTypes() {
|
||||
return TypeAnnotationParser.buildAnnotatedTypes(getTypeAnnotationBytes0(),
|
||||
sun.misc.SharedSecrets.getJavaLangAccess().
|
||||
getConstantPool(getDeclaringClass()),
|
||||
this,
|
||||
getDeclaringClass(),
|
||||
getGenericExceptionTypes(),
|
||||
TypeAnnotation.TypeAnnotationTarget.THROWS);
|
||||
}
|
||||
|
||||
}
|
||||
1185
jdkSrc/jdk8/java/lang/reflect/Field.java
Normal file
1185
jdkSrc/jdk8/java/lang/reflect/Field.java
Normal file
File diff suppressed because it is too large
Load Diff
52
jdkSrc/jdk8/java/lang/reflect/GenericArrayType.java
Normal file
52
jdkSrc/jdk8/java/lang/reflect/GenericArrayType.java
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang.reflect;
|
||||
|
||||
/**
|
||||
* {@code GenericArrayType} represents an array type whose component
|
||||
* type is either a parameterized type or a type variable.
|
||||
* @since 1.5
|
||||
*/
|
||||
public interface GenericArrayType extends Type {
|
||||
/**
|
||||
* Returns a {@code Type} object representing the component type
|
||||
* of this array. This method creates the component type of the
|
||||
* array. See the declaration of {@link
|
||||
* java.lang.reflect.ParameterizedType ParameterizedType} for the
|
||||
* semantics of the creation process for parameterized types and
|
||||
* see {@link java.lang.reflect.TypeVariable TypeVariable} for the
|
||||
* creation process for type variables.
|
||||
*
|
||||
* @return a {@code Type} object representing the component type
|
||||
* of this array
|
||||
* @throws TypeNotPresentException if the underlying array type's
|
||||
* component type refers to a non-existent type declaration
|
||||
* @throws MalformedParameterizedTypeException if the
|
||||
* underlying array type's component type refers to a
|
||||
* parameterized type that cannot be instantiated for any reason
|
||||
*/
|
||||
Type getGenericComponentType();
|
||||
}
|
||||
49
jdkSrc/jdk8/java/lang/reflect/GenericDeclaration.java
Normal file
49
jdkSrc/jdk8/java/lang/reflect/GenericDeclaration.java
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang.reflect;
|
||||
|
||||
/**
|
||||
* A common interface for all entities that declare type variables.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public interface GenericDeclaration extends AnnotatedElement {
|
||||
/**
|
||||
* Returns an array of {@code TypeVariable} objects that
|
||||
* represent the type variables declared by the generic
|
||||
* declaration represented by this {@code GenericDeclaration}
|
||||
* object, in declaration order. Returns an array of length 0 if
|
||||
* the underlying generic declaration declares no type variables.
|
||||
*
|
||||
* @return an array of {@code TypeVariable} objects that represent
|
||||
* the type variables declared by this generic declaration
|
||||
* @throws GenericSignatureFormatError if the generic
|
||||
* signature of this generic declaration does not conform to
|
||||
* the format specified in
|
||||
* <cite>The Java™ Virtual Machine Specification</cite>
|
||||
*/
|
||||
public TypeVariable<?>[] getTypeParameters();
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang.reflect;
|
||||
|
||||
|
||||
/**
|
||||
* Thrown when a syntactically malformed signature attribute is
|
||||
* encountered by a reflective method that needs to interpret the
|
||||
* generic signature information for a type, method or constructor.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public class GenericSignatureFormatError extends ClassFormatError {
|
||||
private static final long serialVersionUID = 6709919147137911034L;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code GenericSignatureFormatError}.
|
||||
*
|
||||
*/
|
||||
public GenericSignatureFormatError() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code GenericSignatureFormatError} with the
|
||||
* specified message.
|
||||
*
|
||||
* @param message the detail message, may be {@code null}
|
||||
*/
|
||||
public GenericSignatureFormatError(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
95
jdkSrc/jdk8/java/lang/reflect/InvocationHandler.java
Normal file
95
jdkSrc/jdk8/java/lang/reflect/InvocationHandler.java
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2006, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang.reflect;
|
||||
|
||||
/**
|
||||
* {@code InvocationHandler} is the interface implemented by
|
||||
* the <i>invocation handler</i> of a proxy instance.
|
||||
*
|
||||
* <p>Each proxy instance has an associated invocation handler.
|
||||
* When a method is invoked on a proxy instance, the method
|
||||
* invocation is encoded and dispatched to the {@code invoke}
|
||||
* method of its invocation handler.
|
||||
*
|
||||
* @author Peter Jones
|
||||
* @see Proxy
|
||||
* @since 1.3
|
||||
*/
|
||||
public interface InvocationHandler {
|
||||
|
||||
/**
|
||||
* Processes a method invocation on a proxy instance and returns
|
||||
* the result. This method will be invoked on an invocation handler
|
||||
* when a method is invoked on a proxy instance that it is
|
||||
* associated with.
|
||||
*
|
||||
* @param proxy the proxy instance that the method was invoked on
|
||||
*
|
||||
* @param method the {@code Method} instance corresponding to
|
||||
* the interface method invoked on the proxy instance. The declaring
|
||||
* class of the {@code Method} object will be the interface that
|
||||
* the method was declared in, which may be a superinterface of the
|
||||
* proxy interface that the proxy class inherits the method through.
|
||||
*
|
||||
* @param args an array of objects containing the values of the
|
||||
* arguments passed in the method invocation on the proxy instance,
|
||||
* or {@code null} if interface method takes no arguments.
|
||||
* Arguments of primitive types are wrapped in instances of the
|
||||
* appropriate primitive wrapper class, such as
|
||||
* {@code java.lang.Integer} or {@code java.lang.Boolean}.
|
||||
*
|
||||
* @return the value to return from the method invocation on the
|
||||
* proxy instance. If the declared return type of the interface
|
||||
* method is a primitive type, then the value returned by
|
||||
* this method must be an instance of the corresponding primitive
|
||||
* wrapper class; otherwise, it must be a type assignable to the
|
||||
* declared return type. If the value returned by this method is
|
||||
* {@code null} and the interface method's return type is
|
||||
* primitive, then a {@code NullPointerException} will be
|
||||
* thrown by the method invocation on the proxy instance. If the
|
||||
* value returned by this method is otherwise not compatible with
|
||||
* the interface method's declared return type as described above,
|
||||
* a {@code ClassCastException} will be thrown by the method
|
||||
* invocation on the proxy instance.
|
||||
*
|
||||
* @throws Throwable the exception to throw from the method
|
||||
* invocation on the proxy instance. The exception's type must be
|
||||
* assignable either to any of the exception types declared in the
|
||||
* {@code throws} clause of the interface method or to the
|
||||
* unchecked exception types {@code java.lang.RuntimeException}
|
||||
* or {@code java.lang.Error}. If a checked exception is
|
||||
* thrown by this method that is not assignable to any of the
|
||||
* exception types declared in the {@code throws} clause of
|
||||
* the interface method, then an
|
||||
* {@link UndeclaredThrowableException} containing the
|
||||
* exception that was thrown by this method will be thrown by the
|
||||
* method invocation on the proxy instance.
|
||||
*
|
||||
* @see UndeclaredThrowableException
|
||||
*/
|
||||
public Object invoke(Object proxy, Method method, Object[] args)
|
||||
throws Throwable;
|
||||
}
|
||||
111
jdkSrc/jdk8/java/lang/reflect/InvocationTargetException.java
Normal file
111
jdkSrc/jdk8/java/lang/reflect/InvocationTargetException.java
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang.reflect;
|
||||
|
||||
/**
|
||||
* InvocationTargetException is a checked exception that wraps
|
||||
* an exception thrown by an invoked method or constructor.
|
||||
*
|
||||
* <p>As of release 1.4, this exception has been retrofitted to conform to
|
||||
* the general purpose exception-chaining mechanism. The "target exception"
|
||||
* that is provided at construction time and accessed via the
|
||||
* {@link #getTargetException()} method is now known as the <i>cause</i>,
|
||||
* and may be accessed via the {@link Throwable#getCause()} method,
|
||||
* as well as the aforementioned "legacy method."
|
||||
*
|
||||
* @see Method
|
||||
* @see Constructor
|
||||
*/
|
||||
public class InvocationTargetException extends ReflectiveOperationException {
|
||||
/**
|
||||
* Use serialVersionUID from JDK 1.1.X for interoperability
|
||||
*/
|
||||
private static final long serialVersionUID = 4085088731926701167L;
|
||||
|
||||
/**
|
||||
* This field holds the target if the
|
||||
* InvocationTargetException(Throwable target) constructor was
|
||||
* used to instantiate the object
|
||||
*
|
||||
* @serial
|
||||
*
|
||||
*/
|
||||
private Throwable target;
|
||||
|
||||
/**
|
||||
* Constructs an {@code InvocationTargetException} with
|
||||
* {@code null} as the target exception.
|
||||
*/
|
||||
protected InvocationTargetException() {
|
||||
super((Throwable)null); // Disallow initCause
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a InvocationTargetException with a target exception.
|
||||
*
|
||||
* @param target the target exception
|
||||
*/
|
||||
public InvocationTargetException(Throwable target) {
|
||||
super((Throwable)null); // Disallow initCause
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a InvocationTargetException with a target exception
|
||||
* and a detail message.
|
||||
*
|
||||
* @param target the target exception
|
||||
* @param s the detail message
|
||||
*/
|
||||
public InvocationTargetException(Throwable target, String s) {
|
||||
super(s, null); // Disallow initCause
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the thrown target exception.
|
||||
*
|
||||
* <p>This method predates the general-purpose exception chaining facility.
|
||||
* The {@link Throwable#getCause()} method is now the preferred means of
|
||||
* obtaining this information.
|
||||
*
|
||||
* @return the thrown target exception (cause of this exception).
|
||||
*/
|
||||
public Throwable getTargetException() {
|
||||
return target;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the cause of this exception (the thrown target exception,
|
||||
* which may be {@code null}).
|
||||
*
|
||||
* @return the cause of this exception.
|
||||
* @since 1.4
|
||||
*/
|
||||
public Throwable getCause() {
|
||||
return target;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
package java.lang.reflect;
|
||||
|
||||
/**
|
||||
* Thrown when a semantically malformed parameterized type is
|
||||
* encountered by a reflective method that needs to instantiate it.
|
||||
* For example, if the number of type arguments to a parameterized type
|
||||
* is wrong.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public class MalformedParameterizedTypeException extends RuntimeException {
|
||||
private static final long serialVersionUID = -5696557788586220964L;
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang.reflect;
|
||||
|
||||
/**
|
||||
* Thrown when {@link java.lang.reflect.Executable#getParameters the
|
||||
* java.lang.reflect package} attempts to read method parameters from
|
||||
* a class file and determines that one or more parameters are
|
||||
* malformed.
|
||||
*
|
||||
* <p>The following is a list of conditions under which this exception
|
||||
* can be thrown:
|
||||
* <ul>
|
||||
* <li> The number of parameters (parameter_count) is wrong for the method
|
||||
* <li> A constant pool index is out of bounds.
|
||||
* <li> A constant pool index does not refer to a UTF-8 entry
|
||||
* <li> A parameter's name is "", or contains an illegal character
|
||||
* <li> The flags field contains an illegal flag (something other than
|
||||
* FINAL, SYNTHETIC, or MANDATED)
|
||||
* </ul>
|
||||
*
|
||||
* See {@link java.lang.reflect.Executable#getParameters} for more
|
||||
* information.
|
||||
*
|
||||
* @see java.lang.reflect.Executable#getParameters
|
||||
* @since 1.8
|
||||
*/
|
||||
public class MalformedParametersException extends RuntimeException {
|
||||
|
||||
/**
|
||||
* Version for serialization.
|
||||
*/
|
||||
private static final long serialVersionUID = 20130919L;
|
||||
|
||||
/**
|
||||
* Create a {@code MalformedParametersException} with an empty
|
||||
* reason.
|
||||
*/
|
||||
public MalformedParametersException() {}
|
||||
|
||||
/**
|
||||
* Create a {@code MalformedParametersException}.
|
||||
*
|
||||
* @param reason The reason for the exception.
|
||||
*/
|
||||
public MalformedParametersException(String reason) {
|
||||
super(reason);
|
||||
}
|
||||
}
|
||||
92
jdkSrc/jdk8/java/lang/reflect/Member.java
Normal file
92
jdkSrc/jdk8/java/lang/reflect/Member.java
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang.reflect;
|
||||
|
||||
/**
|
||||
* Member is an interface that reflects identifying information about
|
||||
* a single member (a field or a method) or a constructor.
|
||||
*
|
||||
* @see java.lang.Class
|
||||
* @see Field
|
||||
* @see Method
|
||||
* @see Constructor
|
||||
*
|
||||
* @author Nakul Saraiya
|
||||
*/
|
||||
public
|
||||
interface Member {
|
||||
|
||||
/**
|
||||
* Identifies the set of all public members of a class or interface,
|
||||
* including inherited members.
|
||||
*/
|
||||
public static final int PUBLIC = 0;
|
||||
|
||||
/**
|
||||
* Identifies the set of declared members of a class or interface.
|
||||
* Inherited members are not included.
|
||||
*/
|
||||
public static final int DECLARED = 1;
|
||||
|
||||
/**
|
||||
* Returns the Class object representing the class or interface
|
||||
* that declares the member or constructor represented by this Member.
|
||||
*
|
||||
* @return an object representing the declaring class of the
|
||||
* underlying member
|
||||
*/
|
||||
public Class<?> getDeclaringClass();
|
||||
|
||||
/**
|
||||
* Returns the simple name of the underlying member or constructor
|
||||
* represented by this Member.
|
||||
*
|
||||
* @return the simple name of the underlying member
|
||||
*/
|
||||
public String getName();
|
||||
|
||||
/**
|
||||
* Returns the Java language modifiers for the member or
|
||||
* constructor represented by this Member, as an integer. The
|
||||
* Modifier class should be used to decode the modifiers in
|
||||
* the integer.
|
||||
*
|
||||
* @return the Java language modifiers for the underlying member
|
||||
* @see Modifier
|
||||
*/
|
||||
public int getModifiers();
|
||||
|
||||
/**
|
||||
* Returns {@code true} if this member was introduced by
|
||||
* the compiler; returns {@code false} otherwise.
|
||||
*
|
||||
* @return true if and only if this member was introduced by
|
||||
* the compiler.
|
||||
* @jls 13.1 The Form of a Binary
|
||||
* @since 1.5
|
||||
*/
|
||||
public boolean isSynthetic();
|
||||
}
|
||||
655
jdkSrc/jdk8/java/lang/reflect/Method.java
Normal file
655
jdkSrc/jdk8/java/lang/reflect/Method.java
Normal file
@@ -0,0 +1,655 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang.reflect;
|
||||
|
||||
import sun.reflect.CallerSensitive;
|
||||
import sun.reflect.MethodAccessor;
|
||||
import sun.reflect.Reflection;
|
||||
import sun.reflect.generics.repository.MethodRepository;
|
||||
import sun.reflect.generics.factory.CoreReflectionFactory;
|
||||
import sun.reflect.generics.factory.GenericsFactory;
|
||||
import sun.reflect.generics.scope.MethodScope;
|
||||
import sun.reflect.annotation.AnnotationType;
|
||||
import sun.reflect.annotation.AnnotationParser;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.annotation.AnnotationFormatError;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
* A {@code Method} provides information about, and access to, a single method
|
||||
* on a class or interface. The reflected method may be a class method
|
||||
* or an instance method (including an abstract method).
|
||||
*
|
||||
* <p>A {@code Method} permits widening conversions to occur when matching the
|
||||
* actual parameters to invoke with the underlying method's formal
|
||||
* parameters, but it throws an {@code IllegalArgumentException} if a
|
||||
* narrowing conversion would occur.
|
||||
*
|
||||
* @see Member
|
||||
* @see java.lang.Class
|
||||
* @see java.lang.Class#getMethods()
|
||||
* @see java.lang.Class#getMethod(String, Class[])
|
||||
* @see java.lang.Class#getDeclaredMethods()
|
||||
* @see java.lang.Class#getDeclaredMethod(String, Class[])
|
||||
*
|
||||
* @author Kenneth Russell
|
||||
* @author Nakul Saraiya
|
||||
*/
|
||||
public final class Method extends Executable {
|
||||
private Class<?> clazz;
|
||||
private int slot;
|
||||
// This is guaranteed to be interned by the VM in the 1.4
|
||||
// reflection implementation
|
||||
private String name;
|
||||
private Class<?> returnType;
|
||||
private Class<?>[] parameterTypes;
|
||||
private Class<?>[] exceptionTypes;
|
||||
private int modifiers;
|
||||
// Generics and annotations support
|
||||
private transient String signature;
|
||||
// generic info repository; lazily initialized
|
||||
private transient MethodRepository genericInfo;
|
||||
private byte[] annotations;
|
||||
private byte[] parameterAnnotations;
|
||||
private byte[] annotationDefault;
|
||||
private volatile MethodAccessor methodAccessor;
|
||||
// For sharing of MethodAccessors. This branching structure is
|
||||
// currently only two levels deep (i.e., one root Method and
|
||||
// potentially many Method objects pointing to it.)
|
||||
//
|
||||
// If this branching structure would ever contain cycles, deadlocks can
|
||||
// occur in annotation code.
|
||||
private Method root;
|
||||
|
||||
// Generics infrastructure
|
||||
private String getGenericSignature() {return signature;}
|
||||
|
||||
// Accessor for factory
|
||||
private GenericsFactory getFactory() {
|
||||
// create scope and factory
|
||||
return CoreReflectionFactory.make(this, MethodScope.make(this));
|
||||
}
|
||||
|
||||
// Accessor for generic info repository
|
||||
@Override
|
||||
MethodRepository getGenericInfo() {
|
||||
// lazily initialize repository if necessary
|
||||
if (genericInfo == null) {
|
||||
// create and cache generic info repository
|
||||
genericInfo = MethodRepository.make(getGenericSignature(),
|
||||
getFactory());
|
||||
}
|
||||
return genericInfo; //return cached repository
|
||||
}
|
||||
|
||||
/**
|
||||
* Package-private constructor used by ReflectAccess to enable
|
||||
* instantiation of these objects in Java code from the java.lang
|
||||
* package via sun.reflect.LangReflectAccess.
|
||||
*/
|
||||
Method(Class<?> declaringClass,
|
||||
String name,
|
||||
Class<?>[] parameterTypes,
|
||||
Class<?> returnType,
|
||||
Class<?>[] checkedExceptions,
|
||||
int modifiers,
|
||||
int slot,
|
||||
String signature,
|
||||
byte[] annotations,
|
||||
byte[] parameterAnnotations,
|
||||
byte[] annotationDefault) {
|
||||
this.clazz = declaringClass;
|
||||
this.name = name;
|
||||
this.parameterTypes = parameterTypes;
|
||||
this.returnType = returnType;
|
||||
this.exceptionTypes = checkedExceptions;
|
||||
this.modifiers = modifiers;
|
||||
this.slot = slot;
|
||||
this.signature = signature;
|
||||
this.annotations = annotations;
|
||||
this.parameterAnnotations = parameterAnnotations;
|
||||
this.annotationDefault = annotationDefault;
|
||||
}
|
||||
|
||||
/**
|
||||
* Package-private routine (exposed to java.lang.Class via
|
||||
* ReflectAccess) which returns a copy of this Method. The copy's
|
||||
* "root" field points to this Method.
|
||||
*/
|
||||
Method copy() {
|
||||
// This routine enables sharing of MethodAccessor objects
|
||||
// among Method objects which refer to the same underlying
|
||||
// method in the VM. (All of this contortion is only necessary
|
||||
// because of the "accessibility" bit in AccessibleObject,
|
||||
// which implicitly requires that new java.lang.reflect
|
||||
// objects be fabricated for each reflective call on Class
|
||||
// objects.)
|
||||
if (this.root != null)
|
||||
throw new IllegalArgumentException("Can not copy a non-root Method");
|
||||
|
||||
Method res = new Method(clazz, name, parameterTypes, returnType,
|
||||
exceptionTypes, modifiers, slot, signature,
|
||||
annotations, parameterAnnotations, annotationDefault);
|
||||
res.root = this;
|
||||
// Might as well eagerly propagate this if already present
|
||||
res.methodAccessor = methodAccessor;
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by Excecutable for annotation sharing.
|
||||
*/
|
||||
@Override
|
||||
Executable getRoot() {
|
||||
return root;
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean hasGenericInformation() {
|
||||
return (getGenericSignature() != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
byte[] getAnnotationBytes() {
|
||||
return annotations;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Class<?> getDeclaringClass() {
|
||||
return clazz;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the method represented by this {@code Method}
|
||||
* object, as a {@code String}.
|
||||
*/
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public int getModifiers() {
|
||||
return modifiers;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @throws GenericSignatureFormatError {@inheritDoc}
|
||||
* @since 1.5
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public TypeVariable<Method>[] getTypeParameters() {
|
||||
if (getGenericSignature() != null)
|
||||
return (TypeVariable<Method>[])getGenericInfo().getTypeParameters();
|
||||
else
|
||||
return (TypeVariable<Method>[])new TypeVariable[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@code Class} object that represents the formal return type
|
||||
* of the method represented by this {@code Method} object.
|
||||
*
|
||||
* @return the return type for the method this object represents
|
||||
*/
|
||||
public Class<?> getReturnType() {
|
||||
return returnType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@code Type} object that represents the formal return
|
||||
* type of the method represented by this {@code Method} object.
|
||||
*
|
||||
* <p>If the return type is a parameterized type,
|
||||
* the {@code Type} object returned must accurately reflect
|
||||
* the actual type parameters used in the source code.
|
||||
*
|
||||
* <p>If the return type is a type variable or a parameterized type, it
|
||||
* is created. Otherwise, it is resolved.
|
||||
*
|
||||
* @return a {@code Type} object that represents the formal return
|
||||
* type of the underlying method
|
||||
* @throws GenericSignatureFormatError
|
||||
* if the generic method signature does not conform to the format
|
||||
* specified in
|
||||
* <cite>The Java™ Virtual Machine Specification</cite>
|
||||
* @throws TypeNotPresentException if the underlying method's
|
||||
* return type refers to a non-existent type declaration
|
||||
* @throws MalformedParameterizedTypeException if the
|
||||
* underlying method's return typed refers to a parameterized
|
||||
* type that cannot be instantiated for any reason
|
||||
* @since 1.5
|
||||
*/
|
||||
public Type getGenericReturnType() {
|
||||
if (getGenericSignature() != null) {
|
||||
return getGenericInfo().getReturnType();
|
||||
} else { return getReturnType();}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Class<?>[] getParameterTypes() {
|
||||
return parameterTypes.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 1.8
|
||||
*/
|
||||
public int getParameterCount() { return parameterTypes.length; }
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @throws GenericSignatureFormatError {@inheritDoc}
|
||||
* @throws TypeNotPresentException {@inheritDoc}
|
||||
* @throws MalformedParameterizedTypeException {@inheritDoc}
|
||||
* @since 1.5
|
||||
*/
|
||||
@Override
|
||||
public Type[] getGenericParameterTypes() {
|
||||
return super.getGenericParameterTypes();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Class<?>[] getExceptionTypes() {
|
||||
return exceptionTypes.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @throws GenericSignatureFormatError {@inheritDoc}
|
||||
* @throws TypeNotPresentException {@inheritDoc}
|
||||
* @throws MalformedParameterizedTypeException {@inheritDoc}
|
||||
* @since 1.5
|
||||
*/
|
||||
@Override
|
||||
public Type[] getGenericExceptionTypes() {
|
||||
return super.getGenericExceptionTypes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this {@code Method} against the specified object. Returns
|
||||
* true if the objects are the same. Two {@code Methods} are the same if
|
||||
* they were declared by the same class and have the same name
|
||||
* and formal parameter types and return type.
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
if (obj != null && obj instanceof Method) {
|
||||
Method other = (Method)obj;
|
||||
if ((getDeclaringClass() == other.getDeclaringClass())
|
||||
&& (getName() == other.getName())) {
|
||||
if (!returnType.equals(other.getReturnType()))
|
||||
return false;
|
||||
return equalParamTypes(parameterTypes, other.parameterTypes);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hashcode for this {@code Method}. The hashcode is computed
|
||||
* as the exclusive-or of the hashcodes for the underlying
|
||||
* method's declaring class name and the method's name.
|
||||
*/
|
||||
public int hashCode() {
|
||||
return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string describing this {@code Method}. The string is
|
||||
* formatted as the method access modifiers, if any, followed by
|
||||
* the method return type, followed by a space, followed by the
|
||||
* class declaring the method, followed by a period, followed by
|
||||
* the method name, followed by a parenthesized, comma-separated
|
||||
* list of the method's formal parameter types. If the method
|
||||
* throws checked exceptions, the parameter list is followed by a
|
||||
* space, followed by the word throws followed by a
|
||||
* comma-separated list of the thrown exception types.
|
||||
* For example:
|
||||
* <pre>
|
||||
* public boolean java.lang.Object.equals(java.lang.Object)
|
||||
* </pre>
|
||||
*
|
||||
* <p>The access modifiers are placed in canonical order as
|
||||
* specified by "The Java Language Specification". This is
|
||||
* {@code public}, {@code protected} or {@code private} first,
|
||||
* and then other modifiers in the following order:
|
||||
* {@code abstract}, {@code default}, {@code static}, {@code final},
|
||||
* {@code synchronized}, {@code native}, {@code strictfp}.
|
||||
*
|
||||
* @return a string describing this {@code Method}
|
||||
*
|
||||
* @jls 8.4.3 Method Modifiers
|
||||
*/
|
||||
public String toString() {
|
||||
return sharedToString(Modifier.methodModifiers(),
|
||||
isDefault(),
|
||||
parameterTypes,
|
||||
exceptionTypes);
|
||||
}
|
||||
|
||||
@Override
|
||||
void specificToStringHeader(StringBuilder sb) {
|
||||
sb.append(getReturnType().getTypeName()).append(' ');
|
||||
sb.append(getDeclaringClass().getTypeName()).append('.');
|
||||
sb.append(getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string describing this {@code Method}, including
|
||||
* type parameters. The string is formatted as the method access
|
||||
* modifiers, if any, followed by an angle-bracketed
|
||||
* comma-separated list of the method's type parameters, if any,
|
||||
* followed by the method's generic return type, followed by a
|
||||
* space, followed by the class declaring the method, followed by
|
||||
* a period, followed by the method name, followed by a
|
||||
* parenthesized, comma-separated list of the method's generic
|
||||
* formal parameter types.
|
||||
*
|
||||
* If this method was declared to take a variable number of
|
||||
* arguments, instead of denoting the last parameter as
|
||||
* "<tt><i>Type</i>[]</tt>", it is denoted as
|
||||
* "<tt><i>Type</i>...</tt>".
|
||||
*
|
||||
* A space is used to separate access modifiers from one another
|
||||
* and from the type parameters or return type. If there are no
|
||||
* type parameters, the type parameter list is elided; if the type
|
||||
* parameter list is present, a space separates the list from the
|
||||
* class name. If the method is declared to throw exceptions, the
|
||||
* parameter list is followed by a space, followed by the word
|
||||
* throws followed by a comma-separated list of the generic thrown
|
||||
* exception types.
|
||||
*
|
||||
* <p>The access modifiers are placed in canonical order as
|
||||
* specified by "The Java Language Specification". This is
|
||||
* {@code public}, {@code protected} or {@code private} first,
|
||||
* and then other modifiers in the following order:
|
||||
* {@code abstract}, {@code default}, {@code static}, {@code final},
|
||||
* {@code synchronized}, {@code native}, {@code strictfp}.
|
||||
*
|
||||
* @return a string describing this {@code Method},
|
||||
* include type parameters
|
||||
*
|
||||
* @since 1.5
|
||||
*
|
||||
* @jls 8.4.3 Method Modifiers
|
||||
*/
|
||||
@Override
|
||||
public String toGenericString() {
|
||||
return sharedToGenericString(Modifier.methodModifiers(), isDefault());
|
||||
}
|
||||
|
||||
@Override
|
||||
void specificToGenericStringHeader(StringBuilder sb) {
|
||||
Type genRetType = getGenericReturnType();
|
||||
sb.append(genRetType.getTypeName()).append(' ');
|
||||
sb.append(getDeclaringClass().getTypeName()).append('.');
|
||||
sb.append(getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes the underlying method represented by this {@code Method}
|
||||
* object, on the specified object with the specified parameters.
|
||||
* Individual parameters are automatically unwrapped to match
|
||||
* primitive formal parameters, and both primitive and reference
|
||||
* parameters are subject to method invocation conversions as
|
||||
* necessary.
|
||||
*
|
||||
* <p>If the underlying method is static, then the specified {@code obj}
|
||||
* argument is ignored. It may be null.
|
||||
*
|
||||
* <p>If the number of formal parameters required by the underlying method is
|
||||
* 0, the supplied {@code args} array may be of length 0 or null.
|
||||
*
|
||||
* <p>If the underlying method is an instance method, it is invoked
|
||||
* using dynamic method lookup as documented in The Java Language
|
||||
* Specification, Second Edition, section 15.12.4.4; in particular,
|
||||
* overriding based on the runtime type of the target object will occur.
|
||||
*
|
||||
* <p>If the underlying method is static, the class that declared
|
||||
* the method is initialized if it has not already been initialized.
|
||||
*
|
||||
* <p>If the method completes normally, the value it returns is
|
||||
* returned to the caller of invoke; if the value has a primitive
|
||||
* type, it is first appropriately wrapped in an object. However,
|
||||
* if the value has the type of an array of a primitive type, the
|
||||
* elements of the array are <i>not</i> wrapped in objects; in
|
||||
* other words, an array of primitive type is returned. If the
|
||||
* underlying method return type is void, the invocation returns
|
||||
* null.
|
||||
*
|
||||
* @param obj the object the underlying method is invoked from
|
||||
* @param args the arguments used for the method call
|
||||
* @return the result of dispatching the method represented by
|
||||
* this object on {@code obj} with parameters
|
||||
* {@code args}
|
||||
*
|
||||
* @exception IllegalAccessException if this {@code Method} object
|
||||
* is enforcing Java language access control and the underlying
|
||||
* method is inaccessible.
|
||||
* @exception IllegalArgumentException if the method is an
|
||||
* instance method and the specified object argument
|
||||
* is not an instance of the class or interface
|
||||
* declaring the underlying method (or of a subclass
|
||||
* or implementor thereof); if the number of actual
|
||||
* and formal parameters differ; if an unwrapping
|
||||
* conversion for primitive arguments fails; or if,
|
||||
* after possible unwrapping, a parameter value
|
||||
* cannot be converted to the corresponding formal
|
||||
* parameter type by a method invocation conversion.
|
||||
* @exception InvocationTargetException if the underlying method
|
||||
* throws an exception.
|
||||
* @exception NullPointerException if the specified object is null
|
||||
* and the method is an instance method.
|
||||
* @exception ExceptionInInitializerError if the initialization
|
||||
* provoked by this method fails.
|
||||
*/
|
||||
@CallerSensitive
|
||||
public Object invoke(Object obj, Object... args)
|
||||
throws IllegalAccessException, IllegalArgumentException,
|
||||
InvocationTargetException
|
||||
{
|
||||
if (!override) {
|
||||
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
checkAccess(caller, clazz, obj, modifiers);
|
||||
}
|
||||
}
|
||||
MethodAccessor ma = methodAccessor; // read volatile
|
||||
if (ma == null) {
|
||||
ma = acquireMethodAccessor();
|
||||
}
|
||||
return ma.invoke(obj, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if this method is a bridge
|
||||
* method; returns {@code false} otherwise.
|
||||
*
|
||||
* @return true if and only if this method is a bridge
|
||||
* method as defined by the Java Language Specification.
|
||||
* @since 1.5
|
||||
*/
|
||||
public boolean isBridge() {
|
||||
return (getModifiers() & Modifier.BRIDGE) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 1.5
|
||||
*/
|
||||
@Override
|
||||
public boolean isVarArgs() {
|
||||
return super.isVarArgs();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @jls 13.1 The Form of a Binary
|
||||
* @since 1.5
|
||||
*/
|
||||
@Override
|
||||
public boolean isSynthetic() {
|
||||
return super.isSynthetic();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if this method is a default
|
||||
* method; returns {@code false} otherwise.
|
||||
*
|
||||
* A default method is a public non-abstract instance method, that
|
||||
* is, a non-static method with a body, declared in an interface
|
||||
* type.
|
||||
*
|
||||
* @return true if and only if this method is a default
|
||||
* method as defined by the Java Language Specification.
|
||||
* @since 1.8
|
||||
*/
|
||||
public boolean isDefault() {
|
||||
// Default methods are public non-abstract instance methods
|
||||
// declared in an interface.
|
||||
return ((getModifiers() & (Modifier.ABSTRACT | Modifier.PUBLIC | Modifier.STATIC)) ==
|
||||
Modifier.PUBLIC) && getDeclaringClass().isInterface();
|
||||
}
|
||||
|
||||
// NOTE that there is no synchronization used here. It is correct
|
||||
// (though not efficient) to generate more than one MethodAccessor
|
||||
// for a given Method. However, avoiding synchronization will
|
||||
// probably make the implementation more scalable.
|
||||
private MethodAccessor acquireMethodAccessor() {
|
||||
// First check to see if one has been created yet, and take it
|
||||
// if so
|
||||
MethodAccessor tmp = null;
|
||||
if (root != null) tmp = root.getMethodAccessor();
|
||||
if (tmp != null) {
|
||||
methodAccessor = tmp;
|
||||
} else {
|
||||
// Otherwise fabricate one and propagate it up to the root
|
||||
tmp = reflectionFactory.newMethodAccessor(this);
|
||||
setMethodAccessor(tmp);
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// Returns MethodAccessor for this Method object, not looking up
|
||||
// the chain to the root
|
||||
MethodAccessor getMethodAccessor() {
|
||||
return methodAccessor;
|
||||
}
|
||||
|
||||
// Sets the MethodAccessor for this Method object and
|
||||
// (recursively) its root
|
||||
void setMethodAccessor(MethodAccessor accessor) {
|
||||
methodAccessor = accessor;
|
||||
// Propagate up
|
||||
if (root != null) {
|
||||
root.setMethodAccessor(accessor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default value for the annotation member represented by
|
||||
* this {@code Method} instance. If the member is of a primitive type,
|
||||
* an instance of the corresponding wrapper type is returned. Returns
|
||||
* null if no default is associated with the member, or if the method
|
||||
* instance does not represent a declared member of an annotation type.
|
||||
*
|
||||
* @return the default value for the annotation member represented
|
||||
* by this {@code Method} instance.
|
||||
* @throws TypeNotPresentException if the annotation is of type
|
||||
* {@link Class} and no definition can be found for the
|
||||
* default class value.
|
||||
* @since 1.5
|
||||
*/
|
||||
public Object getDefaultValue() {
|
||||
if (annotationDefault == null)
|
||||
return null;
|
||||
Class<?> memberType = AnnotationType.invocationHandlerReturnType(
|
||||
getReturnType());
|
||||
Object result = AnnotationParser.parseMemberValue(
|
||||
memberType, ByteBuffer.wrap(annotationDefault),
|
||||
sun.misc.SharedSecrets.getJavaLangAccess().
|
||||
getConstantPool(getDeclaringClass()),
|
||||
getDeclaringClass());
|
||||
if (result instanceof sun.reflect.annotation.ExceptionProxy)
|
||||
throw new AnnotationFormatError("Invalid default: " + this);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
* @since 1.5
|
||||
*/
|
||||
public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
|
||||
return super.getAnnotation(annotationClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 1.5
|
||||
*/
|
||||
public Annotation[] getDeclaredAnnotations() {
|
||||
return super.getDeclaredAnnotations();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 1.5
|
||||
*/
|
||||
@Override
|
||||
public Annotation[][] getParameterAnnotations() {
|
||||
return sharedGetParameterAnnotations(parameterTypes, parameterAnnotations);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 1.8
|
||||
*/
|
||||
@Override
|
||||
public AnnotatedType getAnnotatedReturnType() {
|
||||
return getAnnotatedReturnType0(getGenericReturnType());
|
||||
}
|
||||
|
||||
@Override
|
||||
void handleParameterNumberMismatch(int resultLength, int numParameters) {
|
||||
throw new AnnotationFormatError("Parameter annotations don't match number of parameters");
|
||||
}
|
||||
}
|
||||
496
jdkSrc/jdk8/java/lang/reflect/Modifier.java
Normal file
496
jdkSrc/jdk8/java/lang/reflect/Modifier.java
Normal file
@@ -0,0 +1,496 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang.reflect;
|
||||
|
||||
import java.security.AccessController;
|
||||
import sun.reflect.LangReflectAccess;
|
||||
import sun.reflect.ReflectionFactory;
|
||||
|
||||
/**
|
||||
* The Modifier class provides {@code static} methods and
|
||||
* constants to decode class and member access modifiers. The sets of
|
||||
* modifiers are represented as integers with distinct bit positions
|
||||
* representing different modifiers. The values for the constants
|
||||
* representing the modifiers are taken from the tables in sections 4.1, 4.4, 4.5, and 4.7 of
|
||||
* <cite>The Java™ Virtual Machine Specification</cite>.
|
||||
*
|
||||
* @see Class#getModifiers()
|
||||
* @see Member#getModifiers()
|
||||
*
|
||||
* @author Nakul Saraiya
|
||||
* @author Kenneth Russell
|
||||
*/
|
||||
public class Modifier {
|
||||
|
||||
/*
|
||||
* Bootstrapping protocol between java.lang and java.lang.reflect
|
||||
* packages
|
||||
*/
|
||||
static {
|
||||
sun.reflect.ReflectionFactory factory =
|
||||
AccessController.doPrivileged(
|
||||
new ReflectionFactory.GetReflectionFactoryAction());
|
||||
factory.setLangReflectAccess(new java.lang.reflect.ReflectAccess());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return {@code true} if the integer argument includes the
|
||||
* {@code public} modifier, {@code false} otherwise.
|
||||
*
|
||||
* @param mod a set of modifiers
|
||||
* @return {@code true} if {@code mod} includes the
|
||||
* {@code public} modifier; {@code false} otherwise.
|
||||
*/
|
||||
public static boolean isPublic(int mod) {
|
||||
return (mod & PUBLIC) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return {@code true} if the integer argument includes the
|
||||
* {@code private} modifier, {@code false} otherwise.
|
||||
*
|
||||
* @param mod a set of modifiers
|
||||
* @return {@code true} if {@code mod} includes the
|
||||
* {@code private} modifier; {@code false} otherwise.
|
||||
*/
|
||||
public static boolean isPrivate(int mod) {
|
||||
return (mod & PRIVATE) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return {@code true} if the integer argument includes the
|
||||
* {@code protected} modifier, {@code false} otherwise.
|
||||
*
|
||||
* @param mod a set of modifiers
|
||||
* @return {@code true} if {@code mod} includes the
|
||||
* {@code protected} modifier; {@code false} otherwise.
|
||||
*/
|
||||
public static boolean isProtected(int mod) {
|
||||
return (mod & PROTECTED) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return {@code true} if the integer argument includes the
|
||||
* {@code static} modifier, {@code false} otherwise.
|
||||
*
|
||||
* @param mod a set of modifiers
|
||||
* @return {@code true} if {@code mod} includes the
|
||||
* {@code static} modifier; {@code false} otherwise.
|
||||
*/
|
||||
public static boolean isStatic(int mod) {
|
||||
return (mod & STATIC) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return {@code true} if the integer argument includes the
|
||||
* {@code final} modifier, {@code false} otherwise.
|
||||
*
|
||||
* @param mod a set of modifiers
|
||||
* @return {@code true} if {@code mod} includes the
|
||||
* {@code final} modifier; {@code false} otherwise.
|
||||
*/
|
||||
public static boolean isFinal(int mod) {
|
||||
return (mod & FINAL) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return {@code true} if the integer argument includes the
|
||||
* {@code synchronized} modifier, {@code false} otherwise.
|
||||
*
|
||||
* @param mod a set of modifiers
|
||||
* @return {@code true} if {@code mod} includes the
|
||||
* {@code synchronized} modifier; {@code false} otherwise.
|
||||
*/
|
||||
public static boolean isSynchronized(int mod) {
|
||||
return (mod & SYNCHRONIZED) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return {@code true} if the integer argument includes the
|
||||
* {@code volatile} modifier, {@code false} otherwise.
|
||||
*
|
||||
* @param mod a set of modifiers
|
||||
* @return {@code true} if {@code mod} includes the
|
||||
* {@code volatile} modifier; {@code false} otherwise.
|
||||
*/
|
||||
public static boolean isVolatile(int mod) {
|
||||
return (mod & VOLATILE) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return {@code true} if the integer argument includes the
|
||||
* {@code transient} modifier, {@code false} otherwise.
|
||||
*
|
||||
* @param mod a set of modifiers
|
||||
* @return {@code true} if {@code mod} includes the
|
||||
* {@code transient} modifier; {@code false} otherwise.
|
||||
*/
|
||||
public static boolean isTransient(int mod) {
|
||||
return (mod & TRANSIENT) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return {@code true} if the integer argument includes the
|
||||
* {@code native} modifier, {@code false} otherwise.
|
||||
*
|
||||
* @param mod a set of modifiers
|
||||
* @return {@code true} if {@code mod} includes the
|
||||
* {@code native} modifier; {@code false} otherwise.
|
||||
*/
|
||||
public static boolean isNative(int mod) {
|
||||
return (mod & NATIVE) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return {@code true} if the integer argument includes the
|
||||
* {@code interface} modifier, {@code false} otherwise.
|
||||
*
|
||||
* @param mod a set of modifiers
|
||||
* @return {@code true} if {@code mod} includes the
|
||||
* {@code interface} modifier; {@code false} otherwise.
|
||||
*/
|
||||
public static boolean isInterface(int mod) {
|
||||
return (mod & INTERFACE) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return {@code true} if the integer argument includes the
|
||||
* {@code abstract} modifier, {@code false} otherwise.
|
||||
*
|
||||
* @param mod a set of modifiers
|
||||
* @return {@code true} if {@code mod} includes the
|
||||
* {@code abstract} modifier; {@code false} otherwise.
|
||||
*/
|
||||
public static boolean isAbstract(int mod) {
|
||||
return (mod & ABSTRACT) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return {@code true} if the integer argument includes the
|
||||
* {@code strictfp} modifier, {@code false} otherwise.
|
||||
*
|
||||
* @param mod a set of modifiers
|
||||
* @return {@code true} if {@code mod} includes the
|
||||
* {@code strictfp} modifier; {@code false} otherwise.
|
||||
*/
|
||||
public static boolean isStrict(int mod) {
|
||||
return (mod & STRICT) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a string describing the access modifier flags in
|
||||
* the specified modifier. For example:
|
||||
* <blockquote><pre>
|
||||
* public final synchronized strictfp
|
||||
* </pre></blockquote>
|
||||
* The modifier names are returned in an order consistent with the
|
||||
* suggested modifier orderings given in sections 8.1.1, 8.3.1, 8.4.3, 8.8.3, and 9.1.1 of
|
||||
* <cite>The Java™ Language Specification</cite>.
|
||||
* The full modifier ordering used by this method is:
|
||||
* <blockquote> {@code
|
||||
* public protected private abstract static final transient
|
||||
* volatile synchronized native strictfp
|
||||
* interface } </blockquote>
|
||||
* The {@code interface} modifier discussed in this class is
|
||||
* not a true modifier in the Java language and it appears after
|
||||
* all other modifiers listed by this method. This method may
|
||||
* return a string of modifiers that are not valid modifiers of a
|
||||
* Java entity; in other words, no checking is done on the
|
||||
* possible validity of the combination of modifiers represented
|
||||
* by the input.
|
||||
*
|
||||
* Note that to perform such checking for a known kind of entity,
|
||||
* such as a constructor or method, first AND the argument of
|
||||
* {@code toString} with the appropriate mask from a method like
|
||||
* {@link #constructorModifiers} or {@link #methodModifiers}.
|
||||
*
|
||||
* @param mod a set of modifiers
|
||||
* @return a string representation of the set of modifiers
|
||||
* represented by {@code mod}
|
||||
*/
|
||||
public static String toString(int mod) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
int len;
|
||||
|
||||
if ((mod & PUBLIC) != 0) sb.append("public ");
|
||||
if ((mod & PROTECTED) != 0) sb.append("protected ");
|
||||
if ((mod & PRIVATE) != 0) sb.append("private ");
|
||||
|
||||
/* Canonical order */
|
||||
if ((mod & ABSTRACT) != 0) sb.append("abstract ");
|
||||
if ((mod & STATIC) != 0) sb.append("static ");
|
||||
if ((mod & FINAL) != 0) sb.append("final ");
|
||||
if ((mod & TRANSIENT) != 0) sb.append("transient ");
|
||||
if ((mod & VOLATILE) != 0) sb.append("volatile ");
|
||||
if ((mod & SYNCHRONIZED) != 0) sb.append("synchronized ");
|
||||
if ((mod & NATIVE) != 0) sb.append("native ");
|
||||
if ((mod & STRICT) != 0) sb.append("strictfp ");
|
||||
if ((mod & INTERFACE) != 0) sb.append("interface ");
|
||||
|
||||
if ((len = sb.length()) > 0) /* trim trailing space */
|
||||
return sb.toString().substring(0, len-1);
|
||||
return "";
|
||||
}
|
||||
|
||||
/*
|
||||
* Access modifier flag constants from tables 4.1, 4.4, 4.5, and 4.7 of
|
||||
* <cite>The Java™ Virtual Machine Specification</cite>
|
||||
*/
|
||||
|
||||
/**
|
||||
* The {@code int} value representing the {@code public}
|
||||
* modifier.
|
||||
*/
|
||||
public static final int PUBLIC = 0x00000001;
|
||||
|
||||
/**
|
||||
* The {@code int} value representing the {@code private}
|
||||
* modifier.
|
||||
*/
|
||||
public static final int PRIVATE = 0x00000002;
|
||||
|
||||
/**
|
||||
* The {@code int} value representing the {@code protected}
|
||||
* modifier.
|
||||
*/
|
||||
public static final int PROTECTED = 0x00000004;
|
||||
|
||||
/**
|
||||
* The {@code int} value representing the {@code static}
|
||||
* modifier.
|
||||
*/
|
||||
public static final int STATIC = 0x00000008;
|
||||
|
||||
/**
|
||||
* The {@code int} value representing the {@code final}
|
||||
* modifier.
|
||||
*/
|
||||
public static final int FINAL = 0x00000010;
|
||||
|
||||
/**
|
||||
* The {@code int} value representing the {@code synchronized}
|
||||
* modifier.
|
||||
*/
|
||||
public static final int SYNCHRONIZED = 0x00000020;
|
||||
|
||||
/**
|
||||
* The {@code int} value representing the {@code volatile}
|
||||
* modifier.
|
||||
*/
|
||||
public static final int VOLATILE = 0x00000040;
|
||||
|
||||
/**
|
||||
* The {@code int} value representing the {@code transient}
|
||||
* modifier.
|
||||
*/
|
||||
public static final int TRANSIENT = 0x00000080;
|
||||
|
||||
/**
|
||||
* The {@code int} value representing the {@code native}
|
||||
* modifier.
|
||||
*/
|
||||
public static final int NATIVE = 0x00000100;
|
||||
|
||||
/**
|
||||
* The {@code int} value representing the {@code interface}
|
||||
* modifier.
|
||||
*/
|
||||
public static final int INTERFACE = 0x00000200;
|
||||
|
||||
/**
|
||||
* The {@code int} value representing the {@code abstract}
|
||||
* modifier.
|
||||
*/
|
||||
public static final int ABSTRACT = 0x00000400;
|
||||
|
||||
/**
|
||||
* The {@code int} value representing the {@code strictfp}
|
||||
* modifier.
|
||||
*/
|
||||
public static final int STRICT = 0x00000800;
|
||||
|
||||
// Bits not (yet) exposed in the public API either because they
|
||||
// have different meanings for fields and methods and there is no
|
||||
// way to distinguish between the two in this class, or because
|
||||
// they are not Java programming language keywords
|
||||
static final int BRIDGE = 0x00000040;
|
||||
static final int VARARGS = 0x00000080;
|
||||
static final int SYNTHETIC = 0x00001000;
|
||||
static final int ANNOTATION = 0x00002000;
|
||||
static final int ENUM = 0x00004000;
|
||||
static final int MANDATED = 0x00008000;
|
||||
static boolean isSynthetic(int mod) {
|
||||
return (mod & SYNTHETIC) != 0;
|
||||
}
|
||||
|
||||
static boolean isMandated(int mod) {
|
||||
return (mod & MANDATED) != 0;
|
||||
}
|
||||
|
||||
// Note on the FOO_MODIFIERS fields and fooModifiers() methods:
|
||||
// the sets of modifiers are not guaranteed to be constants
|
||||
// across time and Java SE releases. Therefore, it would not be
|
||||
// appropriate to expose an external interface to this information
|
||||
// that would allow the values to be treated as Java-level
|
||||
// constants since the values could be constant folded and updates
|
||||
// to the sets of modifiers missed. Thus, the fooModifiers()
|
||||
// methods return an unchanging values for a given release, but a
|
||||
// value that can potentially change over time.
|
||||
|
||||
/**
|
||||
* The Java source modifiers that can be applied to a class.
|
||||
* @jls 8.1.1 Class Modifiers
|
||||
*/
|
||||
private static final int CLASS_MODIFIERS =
|
||||
Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE |
|
||||
Modifier.ABSTRACT | Modifier.STATIC | Modifier.FINAL |
|
||||
Modifier.STRICT;
|
||||
|
||||
/**
|
||||
* The Java source modifiers that can be applied to an interface.
|
||||
* @jls 9.1.1 Interface Modifiers
|
||||
*/
|
||||
private static final int INTERFACE_MODIFIERS =
|
||||
Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE |
|
||||
Modifier.ABSTRACT | Modifier.STATIC | Modifier.STRICT;
|
||||
|
||||
|
||||
/**
|
||||
* The Java source modifiers that can be applied to a constructor.
|
||||
* @jls 8.8.3 Constructor Modifiers
|
||||
*/
|
||||
private static final int CONSTRUCTOR_MODIFIERS =
|
||||
Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE;
|
||||
|
||||
/**
|
||||
* The Java source modifiers that can be applied to a method.
|
||||
* @jls8.4.3 Method Modifiers
|
||||
*/
|
||||
private static final int METHOD_MODIFIERS =
|
||||
Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE |
|
||||
Modifier.ABSTRACT | Modifier.STATIC | Modifier.FINAL |
|
||||
Modifier.SYNCHRONIZED | Modifier.NATIVE | Modifier.STRICT;
|
||||
|
||||
/**
|
||||
* The Java source modifiers that can be applied to a field.
|
||||
* @jls 8.3.1 Field Modifiers
|
||||
*/
|
||||
private static final int FIELD_MODIFIERS =
|
||||
Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE |
|
||||
Modifier.STATIC | Modifier.FINAL | Modifier.TRANSIENT |
|
||||
Modifier.VOLATILE;
|
||||
|
||||
/**
|
||||
* The Java source modifiers that can be applied to a method or constructor parameter.
|
||||
* @jls 8.4.1 Formal Parameters
|
||||
*/
|
||||
private static final int PARAMETER_MODIFIERS =
|
||||
Modifier.FINAL;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static final int ACCESS_MODIFIERS =
|
||||
Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE;
|
||||
|
||||
/**
|
||||
* Return an {@code int} value OR-ing together the source language
|
||||
* modifiers that can be applied to a class.
|
||||
* @return an {@code int} value OR-ing together the source language
|
||||
* modifiers that can be applied to a class.
|
||||
*
|
||||
* @jls 8.1.1 Class Modifiers
|
||||
* @since 1.7
|
||||
*/
|
||||
public static int classModifiers() {
|
||||
return CLASS_MODIFIERS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an {@code int} value OR-ing together the source language
|
||||
* modifiers that can be applied to an interface.
|
||||
* @return an {@code int} value OR-ing together the source language
|
||||
* modifiers that can be applied to an interface.
|
||||
*
|
||||
* @jls 9.1.1 Interface Modifiers
|
||||
* @since 1.7
|
||||
*/
|
||||
public static int interfaceModifiers() {
|
||||
return INTERFACE_MODIFIERS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an {@code int} value OR-ing together the source language
|
||||
* modifiers that can be applied to a constructor.
|
||||
* @return an {@code int} value OR-ing together the source language
|
||||
* modifiers that can be applied to a constructor.
|
||||
*
|
||||
* @jls 8.8.3 Constructor Modifiers
|
||||
* @since 1.7
|
||||
*/
|
||||
public static int constructorModifiers() {
|
||||
return CONSTRUCTOR_MODIFIERS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an {@code int} value OR-ing together the source language
|
||||
* modifiers that can be applied to a method.
|
||||
* @return an {@code int} value OR-ing together the source language
|
||||
* modifiers that can be applied to a method.
|
||||
*
|
||||
* @jls 8.4.3 Method Modifiers
|
||||
* @since 1.7
|
||||
*/
|
||||
public static int methodModifiers() {
|
||||
return METHOD_MODIFIERS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an {@code int} value OR-ing together the source language
|
||||
* modifiers that can be applied to a field.
|
||||
* @return an {@code int} value OR-ing together the source language
|
||||
* modifiers that can be applied to a field.
|
||||
*
|
||||
* @jls 8.3.1 Field Modifiers
|
||||
* @since 1.7
|
||||
*/
|
||||
public static int fieldModifiers() {
|
||||
return FIELD_MODIFIERS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an {@code int} value OR-ing together the source language
|
||||
* modifiers that can be applied to a parameter.
|
||||
* @return an {@code int} value OR-ing together the source language
|
||||
* modifiers that can be applied to a parameter.
|
||||
*
|
||||
* @jls 8.4.1 Formal Parameters
|
||||
* @since 1.8
|
||||
*/
|
||||
public static int parameterModifiers() {
|
||||
return PARAMETER_MODIFIERS;
|
||||
}
|
||||
}
|
||||
349
jdkSrc/jdk8/java/lang/reflect/Parameter.java
Normal file
349
jdkSrc/jdk8/java/lang/reflect/Parameter.java
Normal file
@@ -0,0 +1,349 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package java.lang.reflect;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import sun.reflect.annotation.AnnotationSupport;
|
||||
|
||||
/**
|
||||
* Information about method parameters.
|
||||
*
|
||||
* A {@code Parameter} provides information about method parameters,
|
||||
* including its name and modifiers. It also provides an alternate
|
||||
* means of obtaining attributes for the parameter.
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
public final class Parameter implements AnnotatedElement {
|
||||
|
||||
private final String name;
|
||||
private final int modifiers;
|
||||
private final Executable executable;
|
||||
private final int index;
|
||||
|
||||
/**
|
||||
* Package-private constructor for {@code Parameter}.
|
||||
*
|
||||
* If method parameter data is present in the classfile, then the
|
||||
* JVM creates {@code Parameter} objects directly. If it is
|
||||
* absent, however, then {@code Executable} uses this constructor
|
||||
* to synthesize them.
|
||||
*
|
||||
* @param name The name of the parameter.
|
||||
* @param modifiers The modifier flags for the parameter.
|
||||
* @param executable The executable which defines this parameter.
|
||||
* @param index The index of the parameter.
|
||||
*/
|
||||
Parameter(String name,
|
||||
int modifiers,
|
||||
Executable executable,
|
||||
int index) {
|
||||
this.name = name;
|
||||
this.modifiers = modifiers;
|
||||
this.executable = executable;
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares based on the executable and the index.
|
||||
*
|
||||
* @param obj The object to compare.
|
||||
* @return Whether or not this is equal to the argument.
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
if(obj instanceof Parameter) {
|
||||
Parameter other = (Parameter)obj;
|
||||
return (other.executable.equals(executable) &&
|
||||
other.index == index);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hash code based on the executable's hash code and the
|
||||
* index.
|
||||
*
|
||||
* @return A hash code based on the executable's hash code.
|
||||
*/
|
||||
public int hashCode() {
|
||||
return executable.hashCode() ^ index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the parameter has a name according to the class
|
||||
* file; returns false otherwise. Whether a parameter has a name
|
||||
* is determined by the {@literal MethodParameters} attribute of
|
||||
* the method which declares the parameter.
|
||||
*
|
||||
* @return true if and only if the parameter has a name according
|
||||
* to the class file.
|
||||
*/
|
||||
public boolean isNamePresent() {
|
||||
return executable.hasRealParameterData() && name != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string describing this parameter. The format is the
|
||||
* modifiers for the parameter, if any, in canonical order as
|
||||
* recommended by <cite>The Java™ Language
|
||||
* Specification</cite>, followed by the fully- qualified type of
|
||||
* the parameter (excluding the last [] if the parameter is
|
||||
* variable arity), followed by "..." if the parameter is variable
|
||||
* arity, followed by a space, followed by the name of the
|
||||
* parameter.
|
||||
*
|
||||
* @return A string representation of the parameter and associated
|
||||
* information.
|
||||
*/
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
final Type type = getParameterizedType();
|
||||
final String typename = type.getTypeName();
|
||||
|
||||
sb.append(Modifier.toString(getModifiers()));
|
||||
|
||||
if(0 != modifiers)
|
||||
sb.append(' ');
|
||||
|
||||
if(isVarArgs())
|
||||
sb.append(typename.replaceFirst("\\[\\]$", "..."));
|
||||
else
|
||||
sb.append(typename);
|
||||
|
||||
sb.append(' ');
|
||||
sb.append(getName());
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the {@code Executable} which declares this parameter.
|
||||
*
|
||||
* @return The {@code Executable} declaring this parameter.
|
||||
*/
|
||||
public Executable getDeclaringExecutable() {
|
||||
return executable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the modifier flags for this the parameter represented by
|
||||
* this {@code Parameter} object.
|
||||
*
|
||||
* @return The modifier flags for this parameter.
|
||||
*/
|
||||
public int getModifiers() {
|
||||
return modifiers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the parameter. If the parameter's name is
|
||||
* {@linkplain #isNamePresent() present}, then this method returns
|
||||
* the name provided by the class file. Otherwise, this method
|
||||
* synthesizes a name of the form argN, where N is the index of
|
||||
* the parameter in the descriptor of the method which declares
|
||||
* the parameter.
|
||||
*
|
||||
* @return The name of the parameter, either provided by the class
|
||||
* file or synthesized if the class file does not provide
|
||||
* a name.
|
||||
*/
|
||||
public String getName() {
|
||||
// Note: empty strings as paramete names are now outlawed.
|
||||
// The .equals("") is for compatibility with current JVM
|
||||
// behavior. It may be removed at some point.
|
||||
if(name == null || name.equals(""))
|
||||
return "arg" + index;
|
||||
else
|
||||
return name;
|
||||
}
|
||||
|
||||
// Package-private accessor to the real name field.
|
||||
String getRealName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@code Type} object that identifies the parameterized
|
||||
* type for the parameter represented by this {@code Parameter}
|
||||
* object.
|
||||
*
|
||||
* @return a {@code Type} object identifying the parameterized
|
||||
* type of the parameter represented by this object
|
||||
*/
|
||||
public Type getParameterizedType() {
|
||||
Type tmp = parameterTypeCache;
|
||||
if (null == tmp) {
|
||||
tmp = executable.getAllGenericParameterTypes()[index];
|
||||
parameterTypeCache = tmp;
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
private transient volatile Type parameterTypeCache = null;
|
||||
|
||||
/**
|
||||
* Returns a {@code Class} object that identifies the
|
||||
* declared type for the parameter represented by this
|
||||
* {@code Parameter} object.
|
||||
*
|
||||
* @return a {@code Class} object identifying the declared
|
||||
* type of the parameter represented by this object
|
||||
*/
|
||||
public Class<?> getType() {
|
||||
Class<?> tmp = parameterClassCache;
|
||||
if (null == tmp) {
|
||||
tmp = executable.getParameterTypes()[index];
|
||||
parameterClassCache = tmp;
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an AnnotatedType object that represents the use of a type to
|
||||
* specify the type of the formal parameter represented by this Parameter.
|
||||
*
|
||||
* @return an {@code AnnotatedType} object representing the use of a type
|
||||
* to specify the type of the formal parameter represented by this
|
||||
* Parameter
|
||||
*/
|
||||
public AnnotatedType getAnnotatedType() {
|
||||
// no caching for now
|
||||
return executable.getAnnotatedParameterTypes()[index];
|
||||
}
|
||||
|
||||
private transient volatile Class<?> parameterClassCache = null;
|
||||
|
||||
/**
|
||||
* Returns {@code true} if this parameter is implicitly declared
|
||||
* in source code; returns {@code false} otherwise.
|
||||
*
|
||||
* @return true if and only if this parameter is implicitly
|
||||
* declared as defined by <cite>The Java™ Language
|
||||
* Specification</cite>.
|
||||
*/
|
||||
public boolean isImplicit() {
|
||||
return Modifier.isMandated(getModifiers());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if this parameter is neither implicitly
|
||||
* nor explicitly declared in source code; returns {@code false}
|
||||
* otherwise.
|
||||
*
|
||||
* @jls 13.1 The Form of a Binary
|
||||
* @return true if and only if this parameter is a synthetic
|
||||
* construct as defined by
|
||||
* <cite>The Java™ Language Specification</cite>.
|
||||
*/
|
||||
public boolean isSynthetic() {
|
||||
return Modifier.isSynthetic(getModifiers());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if this parameter represents a variable
|
||||
* argument list; returns {@code false} otherwise.
|
||||
*
|
||||
* @return {@code true} if an only if this parameter represents a
|
||||
* variable argument list.
|
||||
*/
|
||||
public boolean isVarArgs() {
|
||||
return executable.isVarArgs() &&
|
||||
index == executable.getParameterCount() - 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
*/
|
||||
public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
|
||||
Objects.requireNonNull(annotationClass);
|
||||
return annotationClass.cast(declaredAnnotations().get(annotationClass));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
|
||||
Objects.requireNonNull(annotationClass);
|
||||
|
||||
return AnnotationSupport.getDirectlyAndIndirectlyPresent(declaredAnnotations(), annotationClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public Annotation[] getDeclaredAnnotations() {
|
||||
return executable.getParameterAnnotations()[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
*/
|
||||
public <T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass) {
|
||||
// Only annotations on classes are inherited, for all other
|
||||
// objects getDeclaredAnnotation is the same as
|
||||
// getAnnotation.
|
||||
return getAnnotation(annotationClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass) {
|
||||
// Only annotations on classes are inherited, for all other
|
||||
// objects getDeclaredAnnotations is the same as
|
||||
// getAnnotations.
|
||||
return getAnnotationsByType(annotationClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public Annotation[] getAnnotations() {
|
||||
return getDeclaredAnnotations();
|
||||
}
|
||||
|
||||
private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
|
||||
|
||||
private synchronized Map<Class<? extends Annotation>, Annotation> declaredAnnotations() {
|
||||
if(null == declaredAnnotations) {
|
||||
declaredAnnotations =
|
||||
new HashMap<Class<? extends Annotation>, Annotation>();
|
||||
Annotation[] ann = getDeclaredAnnotations();
|
||||
for(int i = 0; i < ann.length; i++)
|
||||
declaredAnnotations.put(ann[i].annotationType(), ann[i]);
|
||||
}
|
||||
return declaredAnnotations;
|
||||
}
|
||||
|
||||
}
|
||||
95
jdkSrc/jdk8/java/lang/reflect/ParameterizedType.java
Normal file
95
jdkSrc/jdk8/java/lang/reflect/ParameterizedType.java
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang.reflect;
|
||||
|
||||
|
||||
/**
|
||||
* ParameterizedType represents a parameterized type such as
|
||||
* Collection<String>.
|
||||
*
|
||||
* <p>A parameterized type is created the first time it is needed by a
|
||||
* reflective method, as specified in this package. When a
|
||||
* parameterized type p is created, the generic type declaration that
|
||||
* p instantiates is resolved, and all type arguments of p are created
|
||||
* recursively. See {@link java.lang.reflect.TypeVariable
|
||||
* TypeVariable} for details on the creation process for type
|
||||
* variables. Repeated creation of a parameterized type has no effect.
|
||||
*
|
||||
* <p>Instances of classes that implement this interface must implement
|
||||
* an equals() method that equates any two instances that share the
|
||||
* same generic type declaration and have equal type parameters.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public interface ParameterizedType extends Type {
|
||||
/**
|
||||
* Returns an array of {@code Type} objects representing the actual type
|
||||
* arguments to this type.
|
||||
*
|
||||
* <p>Note that in some cases, the returned array be empty. This can occur
|
||||
* if this type represents a non-parameterized type nested within
|
||||
* a parameterized type.
|
||||
*
|
||||
* @return an array of {@code Type} objects representing the actual type
|
||||
* arguments to this type
|
||||
* @throws TypeNotPresentException if any of the
|
||||
* actual type arguments refers to a non-existent type declaration
|
||||
* @throws MalformedParameterizedTypeException if any of the
|
||||
* actual type parameters refer to a parameterized type that cannot
|
||||
* be instantiated for any reason
|
||||
* @since 1.5
|
||||
*/
|
||||
Type[] getActualTypeArguments();
|
||||
|
||||
/**
|
||||
* Returns the {@code Type} object representing the class or interface
|
||||
* that declared this type.
|
||||
*
|
||||
* @return the {@code Type} object representing the class or interface
|
||||
* that declared this type
|
||||
* @since 1.5
|
||||
*/
|
||||
Type getRawType();
|
||||
|
||||
/**
|
||||
* Returns a {@code Type} object representing the type that this type
|
||||
* is a member of. For example, if this type is {@code O<T>.I<S>},
|
||||
* return a representation of {@code O<T>}.
|
||||
*
|
||||
* <p>If this type is a top-level type, {@code null} is returned.
|
||||
*
|
||||
* @return a {@code Type} object representing the type that
|
||||
* this type is a member of. If this type is a top-level type,
|
||||
* {@code null} is returned
|
||||
* @throws TypeNotPresentException if the owner type
|
||||
* refers to a non-existent type declaration
|
||||
* @throws MalformedParameterizedTypeException if the owner type
|
||||
* refers to a parameterized type that cannot be instantiated
|
||||
* for any reason
|
||||
* @since 1.5
|
||||
*/
|
||||
Type getOwnerType();
|
||||
}
|
||||
836
jdkSrc/jdk8/java/lang/reflect/Proxy.java
Normal file
836
jdkSrc/jdk8/java/lang/reflect/Proxy.java
Normal file
@@ -0,0 +1,836 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang.reflect;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.Arrays;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.function.BiFunction;
|
||||
import sun.misc.ProxyGenerator;
|
||||
import sun.misc.VM;
|
||||
import sun.reflect.CallerSensitive;
|
||||
import sun.reflect.Reflection;
|
||||
import sun.reflect.misc.ReflectUtil;
|
||||
import sun.security.util.SecurityConstants;
|
||||
|
||||
/**
|
||||
* {@code Proxy} provides static methods for creating dynamic proxy
|
||||
* classes and instances, and it is also the superclass of all
|
||||
* dynamic proxy classes created by those methods.
|
||||
*
|
||||
* <p>To create a proxy for some interface {@code Foo}:
|
||||
* <pre>
|
||||
* InvocationHandler handler = new MyInvocationHandler(...);
|
||||
* Class<?> proxyClass = Proxy.getProxyClass(Foo.class.getClassLoader(), Foo.class);
|
||||
* Foo f = (Foo) proxyClass.getConstructor(InvocationHandler.class).
|
||||
* newInstance(handler);
|
||||
* </pre>
|
||||
* or more simply:
|
||||
* <pre>
|
||||
* Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
|
||||
* new Class<?>[] { Foo.class },
|
||||
* handler);
|
||||
* </pre>
|
||||
*
|
||||
* <p>A <i>dynamic proxy class</i> (simply referred to as a <i>proxy
|
||||
* class</i> below) is a class that implements a list of interfaces
|
||||
* specified at runtime when the class is created, with behavior as
|
||||
* described below.
|
||||
*
|
||||
* A <i>proxy interface</i> is such an interface that is implemented
|
||||
* by a proxy class.
|
||||
*
|
||||
* A <i>proxy instance</i> is an instance of a proxy class.
|
||||
*
|
||||
* Each proxy instance has an associated <i>invocation handler</i>
|
||||
* object, which implements the interface {@link InvocationHandler}.
|
||||
* A method invocation on a proxy instance through one of its proxy
|
||||
* interfaces will be dispatched to the {@link InvocationHandler#invoke
|
||||
* invoke} method of the instance's invocation handler, passing the proxy
|
||||
* instance, a {@code java.lang.reflect.Method} object identifying
|
||||
* the method that was invoked, and an array of type {@code Object}
|
||||
* containing the arguments. The invocation handler processes the
|
||||
* encoded method invocation as appropriate and the result that it
|
||||
* returns will be returned as the result of the method invocation on
|
||||
* the proxy instance.
|
||||
*
|
||||
* <p>A proxy class has the following properties:
|
||||
*
|
||||
* <ul>
|
||||
* <li>Proxy classes are <em>public, final, and not abstract</em> if
|
||||
* all proxy interfaces are public.</li>
|
||||
*
|
||||
* <li>Proxy classes are <em>non-public, final, and not abstract</em> if
|
||||
* any of the proxy interfaces is non-public.</li>
|
||||
*
|
||||
* <li>The unqualified name of a proxy class is unspecified. The space
|
||||
* of class names that begin with the string {@code "$Proxy"}
|
||||
* should be, however, reserved for proxy classes.
|
||||
*
|
||||
* <li>A proxy class extends {@code java.lang.reflect.Proxy}.
|
||||
*
|
||||
* <li>A proxy class implements exactly the interfaces specified at its
|
||||
* creation, in the same order.
|
||||
*
|
||||
* <li>If a proxy class implements a non-public interface, then it will
|
||||
* be defined in the same package as that interface. Otherwise, the
|
||||
* package of a proxy class is also unspecified. Note that package
|
||||
* sealing will not prevent a proxy class from being successfully defined
|
||||
* in a particular package at runtime, and neither will classes already
|
||||
* defined by the same class loader and the same package with particular
|
||||
* signers.
|
||||
*
|
||||
* <li>Since a proxy class implements all of the interfaces specified at
|
||||
* its creation, invoking {@code getInterfaces} on its
|
||||
* {@code Class} object will return an array containing the same
|
||||
* list of interfaces (in the order specified at its creation), invoking
|
||||
* {@code getMethods} on its {@code Class} object will return
|
||||
* an array of {@code Method} objects that include all of the
|
||||
* methods in those interfaces, and invoking {@code getMethod} will
|
||||
* find methods in the proxy interfaces as would be expected.
|
||||
*
|
||||
* <li>The {@link Proxy#isProxyClass Proxy.isProxyClass} method will
|
||||
* return true if it is passed a proxy class-- a class returned by
|
||||
* {@code Proxy.getProxyClass} or the class of an object returned by
|
||||
* {@code Proxy.newProxyInstance}-- and false otherwise.
|
||||
*
|
||||
* <li>The {@code java.security.ProtectionDomain} of a proxy class
|
||||
* is the same as that of system classes loaded by the bootstrap class
|
||||
* loader, such as {@code java.lang.Object}, because the code for a
|
||||
* proxy class is generated by trusted system code. This protection
|
||||
* domain will typically be granted
|
||||
* {@code java.security.AllPermission}.
|
||||
*
|
||||
* <li>Each proxy class has one public constructor that takes one argument,
|
||||
* an implementation of the interface {@link InvocationHandler}, to set
|
||||
* the invocation handler for a proxy instance. Rather than having to use
|
||||
* the reflection API to access the public constructor, a proxy instance
|
||||
* can be also be created by calling the {@link Proxy#newProxyInstance
|
||||
* Proxy.newProxyInstance} method, which combines the actions of calling
|
||||
* {@link Proxy#getProxyClass Proxy.getProxyClass} with invoking the
|
||||
* constructor with an invocation handler.
|
||||
* </ul>
|
||||
*
|
||||
* <p>A proxy instance has the following properties:
|
||||
*
|
||||
* <ul>
|
||||
* <li>Given a proxy instance {@code proxy} and one of the
|
||||
* interfaces implemented by its proxy class {@code Foo}, the
|
||||
* following expression will return true:
|
||||
* <pre>
|
||||
* {@code proxy instanceof Foo}
|
||||
* </pre>
|
||||
* and the following cast operation will succeed (rather than throwing
|
||||
* a {@code ClassCastException}):
|
||||
* <pre>
|
||||
* {@code (Foo) proxy}
|
||||
* </pre>
|
||||
*
|
||||
* <li>Each proxy instance has an associated invocation handler, the one
|
||||
* that was passed to its constructor. The static
|
||||
* {@link Proxy#getInvocationHandler Proxy.getInvocationHandler} method
|
||||
* will return the invocation handler associated with the proxy instance
|
||||
* passed as its argument.
|
||||
*
|
||||
* <li>An interface method invocation on a proxy instance will be
|
||||
* encoded and dispatched to the invocation handler's {@link
|
||||
* InvocationHandler#invoke invoke} method as described in the
|
||||
* documentation for that method.
|
||||
*
|
||||
* <li>An invocation of the {@code hashCode},
|
||||
* {@code equals}, or {@code toString} methods declared in
|
||||
* {@code java.lang.Object} on a proxy instance will be encoded and
|
||||
* dispatched to the invocation handler's {@code invoke} method in
|
||||
* the same manner as interface method invocations are encoded and
|
||||
* dispatched, as described above. The declaring class of the
|
||||
* {@code Method} object passed to {@code invoke} will be
|
||||
* {@code java.lang.Object}. Other public methods of a proxy
|
||||
* instance inherited from {@code java.lang.Object} are not
|
||||
* overridden by a proxy class, so invocations of those methods behave
|
||||
* like they do for instances of {@code java.lang.Object}.
|
||||
* </ul>
|
||||
*
|
||||
* <h3>Methods Duplicated in Multiple Proxy Interfaces</h3>
|
||||
*
|
||||
* <p>When two or more interfaces of a proxy class contain a method with
|
||||
* the same name and parameter signature, the order of the proxy class's
|
||||
* interfaces becomes significant. When such a <i>duplicate method</i>
|
||||
* is invoked on a proxy instance, the {@code Method} object passed
|
||||
* to the invocation handler will not necessarily be the one whose
|
||||
* declaring class is assignable from the reference type of the interface
|
||||
* that the proxy's method was invoked through. This limitation exists
|
||||
* because the corresponding method implementation in the generated proxy
|
||||
* class cannot determine which interface it was invoked through.
|
||||
* Therefore, when a duplicate method is invoked on a proxy instance,
|
||||
* the {@code Method} object for the method in the foremost interface
|
||||
* that contains the method (either directly or inherited through a
|
||||
* superinterface) in the proxy class's list of interfaces is passed to
|
||||
* the invocation handler's {@code invoke} method, regardless of the
|
||||
* reference type through which the method invocation occurred.
|
||||
*
|
||||
* <p>If a proxy interface contains a method with the same name and
|
||||
* parameter signature as the {@code hashCode}, {@code equals},
|
||||
* or {@code toString} methods of {@code java.lang.Object},
|
||||
* when such a method is invoked on a proxy instance, the
|
||||
* {@code Method} object passed to the invocation handler will have
|
||||
* {@code java.lang.Object} as its declaring class. In other words,
|
||||
* the public, non-final methods of {@code java.lang.Object}
|
||||
* logically precede all of the proxy interfaces for the determination of
|
||||
* which {@code Method} object to pass to the invocation handler.
|
||||
*
|
||||
* <p>Note also that when a duplicate method is dispatched to an
|
||||
* invocation handler, the {@code invoke} method may only throw
|
||||
* checked exception types that are assignable to one of the exception
|
||||
* types in the {@code throws} clause of the method in <i>all</i> of
|
||||
* the proxy interfaces that it can be invoked through. If the
|
||||
* {@code invoke} method throws a checked exception that is not
|
||||
* assignable to any of the exception types declared by the method in one
|
||||
* of the proxy interfaces that it can be invoked through, then an
|
||||
* unchecked {@code UndeclaredThrowableException} will be thrown by
|
||||
* the invocation on the proxy instance. This restriction means that not
|
||||
* all of the exception types returned by invoking
|
||||
* {@code getExceptionTypes} on the {@code Method} object
|
||||
* passed to the {@code invoke} method can necessarily be thrown
|
||||
* successfully by the {@code invoke} method.
|
||||
*
|
||||
* @author Peter Jones
|
||||
* @see InvocationHandler
|
||||
* @since 1.3
|
||||
*/
|
||||
public class Proxy implements java.io.Serializable {
|
||||
|
||||
private static final long serialVersionUID = -2222568056686623797L;
|
||||
|
||||
/** parameter types of a proxy class constructor */
|
||||
private static final Class<?>[] constructorParams =
|
||||
{ InvocationHandler.class };
|
||||
|
||||
/**
|
||||
* a cache of proxy classes
|
||||
*/
|
||||
private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
|
||||
proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());
|
||||
|
||||
/**
|
||||
* the invocation handler for this proxy instance.
|
||||
* @serial
|
||||
*/
|
||||
protected InvocationHandler h;
|
||||
|
||||
/**
|
||||
* Prohibits instantiation.
|
||||
*/
|
||||
private Proxy() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code Proxy} instance from a subclass
|
||||
* (typically, a dynamic proxy class) with the specified value
|
||||
* for its invocation handler.
|
||||
*
|
||||
* @param h the invocation handler for this proxy instance
|
||||
*
|
||||
* @throws NullPointerException if the given invocation handler, {@code h},
|
||||
* is {@code null}.
|
||||
*/
|
||||
protected Proxy(InvocationHandler h) {
|
||||
Objects.requireNonNull(h);
|
||||
this.h = h;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@code java.lang.Class} object for a proxy class
|
||||
* given a class loader and an array of interfaces. The proxy class
|
||||
* will be defined by the specified class loader and will implement
|
||||
* all of the supplied interfaces. If any of the given interfaces
|
||||
* is non-public, the proxy class will be non-public. If a proxy class
|
||||
* for the same permutation of interfaces has already been defined by the
|
||||
* class loader, then the existing proxy class will be returned; otherwise,
|
||||
* a proxy class for those interfaces will be generated dynamically
|
||||
* and defined by the class loader.
|
||||
*
|
||||
* <p>There are several restrictions on the parameters that may be
|
||||
* passed to {@code Proxy.getProxyClass}:
|
||||
*
|
||||
* <ul>
|
||||
* <li>All of the {@code Class} objects in the
|
||||
* {@code interfaces} array must represent interfaces, not
|
||||
* classes or primitive types.
|
||||
*
|
||||
* <li>No two elements in the {@code interfaces} array may
|
||||
* refer to identical {@code Class} objects.
|
||||
*
|
||||
* <li>All of the interface types must be visible by name through the
|
||||
* specified class loader. In other words, for class loader
|
||||
* {@code cl} and every interface {@code i}, the following
|
||||
* expression must be true:
|
||||
* <pre>
|
||||
* Class.forName(i.getName(), false, cl) == i
|
||||
* </pre>
|
||||
*
|
||||
* <li>All non-public interfaces must be in the same package;
|
||||
* otherwise, it would not be possible for the proxy class to
|
||||
* implement all of the interfaces, regardless of what package it is
|
||||
* defined in.
|
||||
*
|
||||
* <li>For any set of member methods of the specified interfaces
|
||||
* that have the same signature:
|
||||
* <ul>
|
||||
* <li>If the return type of any of the methods is a primitive
|
||||
* type or void, then all of the methods must have that same
|
||||
* return type.
|
||||
* <li>Otherwise, one of the methods must have a return type that
|
||||
* is assignable to all of the return types of the rest of the
|
||||
* methods.
|
||||
* </ul>
|
||||
*
|
||||
* <li>The resulting proxy class must not exceed any limits imposed
|
||||
* on classes by the virtual machine. For example, the VM may limit
|
||||
* the number of interfaces that a class may implement to 65535; in
|
||||
* that case, the size of the {@code interfaces} array must not
|
||||
* exceed 65535.
|
||||
* </ul>
|
||||
*
|
||||
* <p>If any of these restrictions are violated,
|
||||
* {@code Proxy.getProxyClass} will throw an
|
||||
* {@code IllegalArgumentException}. If the {@code interfaces}
|
||||
* array argument or any of its elements are {@code null}, a
|
||||
* {@code NullPointerException} will be thrown.
|
||||
*
|
||||
* <p>Note that the order of the specified proxy interfaces is
|
||||
* significant: two requests for a proxy class with the same combination
|
||||
* of interfaces but in a different order will result in two distinct
|
||||
* proxy classes.
|
||||
*
|
||||
* @param loader the class loader to define the proxy class
|
||||
* @param interfaces the list of interfaces for the proxy class
|
||||
* to implement
|
||||
* @return a proxy class that is defined in the specified class loader
|
||||
* and that implements the specified interfaces
|
||||
* @throws IllegalArgumentException if any of the restrictions on the
|
||||
* parameters that may be passed to {@code getProxyClass}
|
||||
* are violated
|
||||
* @throws SecurityException if a security manager, <em>s</em>, is present
|
||||
* and any of the following conditions is met:
|
||||
* <ul>
|
||||
* <li> the given {@code loader} is {@code null} and
|
||||
* the caller's class loader is not {@code null} and the
|
||||
* invocation of {@link SecurityManager#checkPermission
|
||||
* s.checkPermission} with
|
||||
* {@code RuntimePermission("getClassLoader")} permission
|
||||
* denies access.</li>
|
||||
* <li> for each proxy interface, {@code intf},
|
||||
* the caller's class loader is not the same as or an
|
||||
* ancestor of the class loader for {@code intf} and
|
||||
* invocation of {@link SecurityManager#checkPackageAccess
|
||||
* s.checkPackageAccess()} denies access to {@code intf}.</li>
|
||||
* </ul>
|
||||
|
||||
* @throws NullPointerException if the {@code interfaces} array
|
||||
* argument or any of its elements are {@code null}
|
||||
*/
|
||||
@CallerSensitive
|
||||
public static Class<?> getProxyClass(ClassLoader loader,
|
||||
Class<?>... interfaces)
|
||||
throws IllegalArgumentException
|
||||
{
|
||||
final Class<?>[] intfs = interfaces.clone();
|
||||
final SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
|
||||
}
|
||||
|
||||
return getProxyClass0(loader, intfs);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check permissions required to create a Proxy class.
|
||||
*
|
||||
* To define a proxy class, it performs the access checks as in
|
||||
* Class.forName (VM will invoke ClassLoader.checkPackageAccess):
|
||||
* 1. "getClassLoader" permission check if loader == null
|
||||
* 2. checkPackageAccess on the interfaces it implements
|
||||
*
|
||||
* To get a constructor and new instance of a proxy class, it performs
|
||||
* the package access check on the interfaces it implements
|
||||
* as in Class.getConstructor.
|
||||
*
|
||||
* If an interface is non-public, the proxy class must be defined by
|
||||
* the defining loader of the interface. If the caller's class loader
|
||||
* is not the same as the defining loader of the interface, the VM
|
||||
* will throw IllegalAccessError when the generated proxy class is
|
||||
* being defined via the defineClass0 method.
|
||||
*/
|
||||
private static void checkProxyAccess(Class<?> caller,
|
||||
ClassLoader loader,
|
||||
Class<?>... interfaces)
|
||||
{
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
ClassLoader ccl = caller.getClassLoader();
|
||||
if (VM.isSystemDomainLoader(loader) && !VM.isSystemDomainLoader(ccl)) {
|
||||
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
|
||||
}
|
||||
ReflectUtil.checkProxyPackageAccess(ccl, interfaces);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a proxy class. Must call the checkProxyAccess method
|
||||
* to perform permission checks before calling this.
|
||||
*/
|
||||
private static Class<?> getProxyClass0(ClassLoader loader,
|
||||
Class<?>... interfaces) {
|
||||
if (interfaces.length > 65535) {
|
||||
throw new IllegalArgumentException("interface limit exceeded");
|
||||
}
|
||||
|
||||
// If the proxy class defined by the given loader implementing
|
||||
// the given interfaces exists, this will simply return the cached copy;
|
||||
// otherwise, it will create the proxy class via the ProxyClassFactory
|
||||
return proxyClassCache.get(loader, interfaces);
|
||||
}
|
||||
|
||||
/*
|
||||
* a key used for proxy class with 0 implemented interfaces
|
||||
*/
|
||||
private static final Object key0 = new Object();
|
||||
|
||||
/*
|
||||
* Key1 and Key2 are optimized for the common use of dynamic proxies
|
||||
* that implement 1 or 2 interfaces.
|
||||
*/
|
||||
|
||||
/*
|
||||
* a key used for proxy class with 1 implemented interface
|
||||
*/
|
||||
private static final class Key1 extends WeakReference<Class<?>> {
|
||||
private final int hash;
|
||||
|
||||
Key1(Class<?> intf) {
|
||||
super(intf);
|
||||
this.hash = intf.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
Class<?> intf;
|
||||
return this == obj ||
|
||||
obj != null &&
|
||||
obj.getClass() == Key1.class &&
|
||||
(intf = get()) != null &&
|
||||
intf == ((Key1) obj).get();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* a key used for proxy class with 2 implemented interfaces
|
||||
*/
|
||||
private static final class Key2 extends WeakReference<Class<?>> {
|
||||
private final int hash;
|
||||
private final WeakReference<Class<?>> ref2;
|
||||
|
||||
Key2(Class<?> intf1, Class<?> intf2) {
|
||||
super(intf1);
|
||||
hash = 31 * intf1.hashCode() + intf2.hashCode();
|
||||
ref2 = new WeakReference<Class<?>>(intf2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
Class<?> intf1, intf2;
|
||||
return this == obj ||
|
||||
obj != null &&
|
||||
obj.getClass() == Key2.class &&
|
||||
(intf1 = get()) != null &&
|
||||
intf1 == ((Key2) obj).get() &&
|
||||
(intf2 = ref2.get()) != null &&
|
||||
intf2 == ((Key2) obj).ref2.get();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* a key used for proxy class with any number of implemented interfaces
|
||||
* (used here for 3 or more only)
|
||||
*/
|
||||
private static final class KeyX {
|
||||
private final int hash;
|
||||
private final WeakReference<Class<?>>[] refs;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
KeyX(Class<?>[] interfaces) {
|
||||
hash = Arrays.hashCode(interfaces);
|
||||
refs = (WeakReference<Class<?>>[])new WeakReference<?>[interfaces.length];
|
||||
for (int i = 0; i < interfaces.length; i++) {
|
||||
refs[i] = new WeakReference<>(interfaces[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return this == obj ||
|
||||
obj != null &&
|
||||
obj.getClass() == KeyX.class &&
|
||||
equals(refs, ((KeyX) obj).refs);
|
||||
}
|
||||
|
||||
private static boolean equals(WeakReference<Class<?>>[] refs1,
|
||||
WeakReference<Class<?>>[] refs2) {
|
||||
if (refs1.length != refs2.length) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < refs1.length; i++) {
|
||||
Class<?> intf = refs1[i].get();
|
||||
if (intf == null || intf != refs2[i].get()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A function that maps an array of interfaces to an optimal key where
|
||||
* Class objects representing interfaces are weakly referenced.
|
||||
*/
|
||||
private static final class KeyFactory
|
||||
implements BiFunction<ClassLoader, Class<?>[], Object>
|
||||
{
|
||||
@Override
|
||||
public Object apply(ClassLoader classLoader, Class<?>[] interfaces) {
|
||||
switch (interfaces.length) {
|
||||
case 1: return new Key1(interfaces[0]); // the most frequent
|
||||
case 2: return new Key2(interfaces[0], interfaces[1]);
|
||||
case 0: return key0;
|
||||
default: return new KeyX(interfaces);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A factory function that generates, defines and returns the proxy class given
|
||||
* the ClassLoader and array of interfaces.
|
||||
*/
|
||||
private static final class ProxyClassFactory
|
||||
implements BiFunction<ClassLoader, Class<?>[], Class<?>>
|
||||
{
|
||||
// prefix for all proxy class names
|
||||
private static final String proxyClassNamePrefix = "$Proxy";
|
||||
|
||||
// next number to use for generation of unique proxy class names
|
||||
private static final AtomicLong nextUniqueNumber = new AtomicLong();
|
||||
|
||||
@Override
|
||||
public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {
|
||||
|
||||
Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
|
||||
for (Class<?> intf : interfaces) {
|
||||
/*
|
||||
* Verify that the class loader resolves the name of this
|
||||
* interface to the same Class object.
|
||||
*/
|
||||
Class<?> interfaceClass = null;
|
||||
try {
|
||||
interfaceClass = Class.forName(intf.getName(), false, loader);
|
||||
} catch (ClassNotFoundException e) {
|
||||
}
|
||||
if (interfaceClass != intf) {
|
||||
throw new IllegalArgumentException(
|
||||
intf + " is not visible from class loader: " + loader);
|
||||
}
|
||||
/*
|
||||
* Verify that the Class object actually represents an
|
||||
* interface.
|
||||
*/
|
||||
if (!interfaceClass.isInterface()) {
|
||||
throw new IllegalArgumentException(
|
||||
interfaceClass.getName() + " is not an interface");
|
||||
}
|
||||
/*
|
||||
* Verify that this interface is not a duplicate.
|
||||
*/
|
||||
if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) {
|
||||
throw new IllegalArgumentException(
|
||||
"repeated interface: " + interfaceClass.getName());
|
||||
}
|
||||
}
|
||||
|
||||
String proxyPkg = null; // package to define proxy class in
|
||||
int accessFlags = Modifier.PUBLIC | Modifier.FINAL;
|
||||
|
||||
/*
|
||||
* Record the package of a non-public proxy interface so that the
|
||||
* proxy class will be defined in the same package. Verify that
|
||||
* all non-public proxy interfaces are in the same package.
|
||||
*/
|
||||
for (Class<?> intf : interfaces) {
|
||||
int flags = intf.getModifiers();
|
||||
if (!Modifier.isPublic(flags)) {
|
||||
accessFlags = Modifier.FINAL;
|
||||
String name = intf.getName();
|
||||
int n = name.lastIndexOf('.');
|
||||
String pkg = ((n == -1) ? "" : name.substring(0, n + 1));
|
||||
if (proxyPkg == null) {
|
||||
proxyPkg = pkg;
|
||||
} else if (!pkg.equals(proxyPkg)) {
|
||||
throw new IllegalArgumentException(
|
||||
"non-public interfaces from different packages");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (proxyPkg == null) {
|
||||
// if no non-public proxy interfaces, use com.sun.proxy package
|
||||
proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";
|
||||
}
|
||||
|
||||
/*
|
||||
* Choose a name for the proxy class to generate.
|
||||
*/
|
||||
long num = nextUniqueNumber.getAndIncrement();
|
||||
String proxyName = proxyPkg + proxyClassNamePrefix + num;
|
||||
|
||||
/*
|
||||
* Generate the specified proxy class.
|
||||
*/
|
||||
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
|
||||
proxyName, interfaces, accessFlags);
|
||||
try {
|
||||
return defineClass0(loader, proxyName,
|
||||
proxyClassFile, 0, proxyClassFile.length);
|
||||
} catch (ClassFormatError e) {
|
||||
/*
|
||||
* A ClassFormatError here means that (barring bugs in the
|
||||
* proxy class generation code) there was some other
|
||||
* invalid aspect of the arguments supplied to the proxy
|
||||
* class creation (such as virtual machine limitations
|
||||
* exceeded).
|
||||
*/
|
||||
throw new IllegalArgumentException(e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an instance of a proxy class for the specified interfaces
|
||||
* that dispatches method invocations to the specified invocation
|
||||
* handler.
|
||||
*
|
||||
* <p>{@code Proxy.newProxyInstance} throws
|
||||
* {@code IllegalArgumentException} for the same reasons that
|
||||
* {@code Proxy.getProxyClass} does.
|
||||
*
|
||||
* @param loader the class loader to define the proxy class
|
||||
* @param interfaces the list of interfaces for the proxy class
|
||||
* to implement
|
||||
* @param h the invocation handler to dispatch method invocations to
|
||||
* @return a proxy instance with the specified invocation handler of a
|
||||
* proxy class that is defined by the specified class loader
|
||||
* and that implements the specified interfaces
|
||||
* @throws IllegalArgumentException if any of the restrictions on the
|
||||
* parameters that may be passed to {@code getProxyClass}
|
||||
* are violated
|
||||
* @throws SecurityException if a security manager, <em>s</em>, is present
|
||||
* and any of the following conditions is met:
|
||||
* <ul>
|
||||
* <li> the given {@code loader} is {@code null} and
|
||||
* the caller's class loader is not {@code null} and the
|
||||
* invocation of {@link SecurityManager#checkPermission
|
||||
* s.checkPermission} with
|
||||
* {@code RuntimePermission("getClassLoader")} permission
|
||||
* denies access;</li>
|
||||
* <li> for each proxy interface, {@code intf},
|
||||
* the caller's class loader is not the same as or an
|
||||
* ancestor of the class loader for {@code intf} and
|
||||
* invocation of {@link SecurityManager#checkPackageAccess
|
||||
* s.checkPackageAccess()} denies access to {@code intf};</li>
|
||||
* <li> any of the given proxy interfaces is non-public and the
|
||||
* caller class is not in the same {@linkplain Package runtime package}
|
||||
* as the non-public interface and the invocation of
|
||||
* {@link SecurityManager#checkPermission s.checkPermission} with
|
||||
* {@code ReflectPermission("newProxyInPackage.{package name}")}
|
||||
* permission denies access.</li>
|
||||
* </ul>
|
||||
* @throws NullPointerException if the {@code interfaces} array
|
||||
* argument or any of its elements are {@code null}, or
|
||||
* if the invocation handler, {@code h}, is
|
||||
* {@code null}
|
||||
*/
|
||||
@CallerSensitive
|
||||
public static Object newProxyInstance(ClassLoader loader,
|
||||
Class<?>[] interfaces,
|
||||
InvocationHandler h)
|
||||
throws IllegalArgumentException
|
||||
{
|
||||
Objects.requireNonNull(h);
|
||||
|
||||
final Class<?>[] intfs = interfaces.clone();
|
||||
final SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
|
||||
}
|
||||
|
||||
/*
|
||||
* Look up or generate the designated proxy class.
|
||||
*/
|
||||
Class<?> cl = getProxyClass0(loader, intfs);
|
||||
|
||||
/*
|
||||
* Invoke its constructor with the designated invocation handler.
|
||||
*/
|
||||
try {
|
||||
if (sm != null) {
|
||||
checkNewProxyPermission(Reflection.getCallerClass(), cl);
|
||||
}
|
||||
|
||||
final Constructor<?> cons = cl.getConstructor(constructorParams);
|
||||
final InvocationHandler ih = h;
|
||||
if (!Modifier.isPublic(cl.getModifiers())) {
|
||||
AccessController.doPrivileged(new PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
cons.setAccessible(true);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
return cons.newInstance(new Object[]{h});
|
||||
} catch (IllegalAccessException|InstantiationException e) {
|
||||
throw new InternalError(e.toString(), e);
|
||||
} catch (InvocationTargetException e) {
|
||||
Throwable t = e.getCause();
|
||||
if (t instanceof RuntimeException) {
|
||||
throw (RuntimeException) t;
|
||||
} else {
|
||||
throw new InternalError(t.toString(), t);
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new InternalError(e.toString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkNewProxyPermission(Class<?> caller, Class<?> proxyClass) {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
if (ReflectUtil.isNonPublicProxyClass(proxyClass)) {
|
||||
ClassLoader ccl = caller.getClassLoader();
|
||||
ClassLoader pcl = proxyClass.getClassLoader();
|
||||
|
||||
// do permission check if the caller is in a different runtime package
|
||||
// of the proxy class
|
||||
int n = proxyClass.getName().lastIndexOf('.');
|
||||
String pkg = (n == -1) ? "" : proxyClass.getName().substring(0, n);
|
||||
|
||||
n = caller.getName().lastIndexOf('.');
|
||||
String callerPkg = (n == -1) ? "" : caller.getName().substring(0, n);
|
||||
|
||||
if (pcl != ccl || !pkg.equals(callerPkg)) {
|
||||
sm.checkPermission(new ReflectPermission("newProxyInPackage." + pkg));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if and only if the specified class was dynamically
|
||||
* generated to be a proxy class using the {@code getProxyClass}
|
||||
* method or the {@code newProxyInstance} method.
|
||||
*
|
||||
* <p>The reliability of this method is important for the ability
|
||||
* to use it to make security decisions, so its implementation should
|
||||
* not just test if the class in question extends {@code Proxy}.
|
||||
*
|
||||
* @param cl the class to test
|
||||
* @return {@code true} if the class is a proxy class and
|
||||
* {@code false} otherwise
|
||||
* @throws NullPointerException if {@code cl} is {@code null}
|
||||
*/
|
||||
public static boolean isProxyClass(Class<?> cl) {
|
||||
return Proxy.class.isAssignableFrom(cl) && proxyClassCache.containsValue(cl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the invocation handler for the specified proxy instance.
|
||||
*
|
||||
* @param proxy the proxy instance to return the invocation handler for
|
||||
* @return the invocation handler for the proxy instance
|
||||
* @throws IllegalArgumentException if the argument is not a
|
||||
* proxy instance
|
||||
* @throws SecurityException if a security manager, <em>s</em>, is present
|
||||
* and the caller's class loader is not the same as or an
|
||||
* ancestor of the class loader for the invocation handler
|
||||
* and invocation of {@link SecurityManager#checkPackageAccess
|
||||
* s.checkPackageAccess()} denies access to the invocation
|
||||
* handler's class.
|
||||
*/
|
||||
@CallerSensitive
|
||||
public static InvocationHandler getInvocationHandler(Object proxy)
|
||||
throws IllegalArgumentException
|
||||
{
|
||||
/*
|
||||
* Verify that the object is actually a proxy instance.
|
||||
*/
|
||||
if (!isProxyClass(proxy.getClass())) {
|
||||
throw new IllegalArgumentException("not a proxy instance");
|
||||
}
|
||||
|
||||
final Proxy p = (Proxy) proxy;
|
||||
final InvocationHandler ih = p.h;
|
||||
if (System.getSecurityManager() != null) {
|
||||
Class<?> ihClass = ih.getClass();
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(),
|
||||
ihClass.getClassLoader()))
|
||||
{
|
||||
ReflectUtil.checkPackageAccess(ihClass);
|
||||
}
|
||||
}
|
||||
|
||||
return ih;
|
||||
}
|
||||
|
||||
private static native Class<?> defineClass0(ClassLoader loader, String name,
|
||||
byte[] b, int off, int len);
|
||||
}
|
||||
150
jdkSrc/jdk8/java/lang/reflect/ReflectAccess.java
Normal file
150
jdkSrc/jdk8/java/lang/reflect/ReflectAccess.java
Normal file
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang.reflect;
|
||||
|
||||
import sun.reflect.MethodAccessor;
|
||||
import sun.reflect.ConstructorAccessor;
|
||||
|
||||
/** Package-private class implementing the
|
||||
sun.reflect.LangReflectAccess interface, allowing the java.lang
|
||||
package to instantiate objects in this package. */
|
||||
|
||||
class ReflectAccess implements sun.reflect.LangReflectAccess {
|
||||
public Field newField(Class<?> declaringClass,
|
||||
String name,
|
||||
Class<?> type,
|
||||
int modifiers,
|
||||
int slot,
|
||||
String signature,
|
||||
byte[] annotations)
|
||||
{
|
||||
return new Field(declaringClass,
|
||||
name,
|
||||
type,
|
||||
modifiers,
|
||||
slot,
|
||||
signature,
|
||||
annotations);
|
||||
}
|
||||
|
||||
public Method newMethod(Class<?> declaringClass,
|
||||
String name,
|
||||
Class<?>[] parameterTypes,
|
||||
Class<?> returnType,
|
||||
Class<?>[] checkedExceptions,
|
||||
int modifiers,
|
||||
int slot,
|
||||
String signature,
|
||||
byte[] annotations,
|
||||
byte[] parameterAnnotations,
|
||||
byte[] annotationDefault)
|
||||
{
|
||||
return new Method(declaringClass,
|
||||
name,
|
||||
parameterTypes,
|
||||
returnType,
|
||||
checkedExceptions,
|
||||
modifiers,
|
||||
slot,
|
||||
signature,
|
||||
annotations,
|
||||
parameterAnnotations,
|
||||
annotationDefault);
|
||||
}
|
||||
|
||||
public <T> Constructor<T> newConstructor(Class<T> declaringClass,
|
||||
Class<?>[] parameterTypes,
|
||||
Class<?>[] checkedExceptions,
|
||||
int modifiers,
|
||||
int slot,
|
||||
String signature,
|
||||
byte[] annotations,
|
||||
byte[] parameterAnnotations)
|
||||
{
|
||||
return new Constructor<>(declaringClass,
|
||||
parameterTypes,
|
||||
checkedExceptions,
|
||||
modifiers,
|
||||
slot,
|
||||
signature,
|
||||
annotations,
|
||||
parameterAnnotations);
|
||||
}
|
||||
|
||||
public MethodAccessor getMethodAccessor(Method m) {
|
||||
return m.getMethodAccessor();
|
||||
}
|
||||
|
||||
public void setMethodAccessor(Method m, MethodAccessor accessor) {
|
||||
m.setMethodAccessor(accessor);
|
||||
}
|
||||
|
||||
public ConstructorAccessor getConstructorAccessor(Constructor<?> c) {
|
||||
return c.getConstructorAccessor();
|
||||
}
|
||||
|
||||
public void setConstructorAccessor(Constructor<?> c,
|
||||
ConstructorAccessor accessor)
|
||||
{
|
||||
c.setConstructorAccessor(accessor);
|
||||
}
|
||||
|
||||
public int getConstructorSlot(Constructor<?> c) {
|
||||
return c.getSlot();
|
||||
}
|
||||
|
||||
public String getConstructorSignature(Constructor<?> c) {
|
||||
return c.getSignature();
|
||||
}
|
||||
|
||||
public byte[] getConstructorAnnotations(Constructor<?> c) {
|
||||
return c.getRawAnnotations();
|
||||
}
|
||||
|
||||
public byte[] getConstructorParameterAnnotations(Constructor<?> c) {
|
||||
return c.getRawParameterAnnotations();
|
||||
}
|
||||
|
||||
public byte[] getExecutableTypeAnnotationBytes(Executable ex) {
|
||||
return ex.getTypeAnnotationBytes();
|
||||
}
|
||||
|
||||
//
|
||||
// Copying routines, needed to quickly fabricate new Field,
|
||||
// Method, and Constructor objects from templates
|
||||
//
|
||||
public Method copyMethod(Method arg) {
|
||||
return arg.copy();
|
||||
}
|
||||
|
||||
public Field copyField(Field arg) {
|
||||
return arg.copy();
|
||||
}
|
||||
|
||||
public <T> Constructor<T> copyConstructor(Constructor<T> arg) {
|
||||
return arg.copy();
|
||||
}
|
||||
}
|
||||
106
jdkSrc/jdk8/java/lang/reflect/ReflectPermission.java
Normal file
106
jdkSrc/jdk8/java/lang/reflect/ReflectPermission.java
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang.reflect;
|
||||
|
||||
/**
|
||||
* The Permission class for reflective operations.
|
||||
* <P>
|
||||
* The following table
|
||||
* provides a summary description of what the permission allows,
|
||||
* and discusses the risks of granting code the permission.
|
||||
*
|
||||
* <table border=1 cellpadding=5 summary="Table shows permission target name, what the permission allows, and associated risks">
|
||||
* <tr>
|
||||
* <th>Permission Target Name</th>
|
||||
* <th>What the Permission Allows</th>
|
||||
* <th>Risks of Allowing this Permission</th>
|
||||
* </tr>
|
||||
*
|
||||
* <tr>
|
||||
* <td>suppressAccessChecks</td>
|
||||
* <td>ability to suppress the standard Java language access checks
|
||||
* on fields and methods in a class; allow access not only public members
|
||||
* but also allow access to default (package) access, protected,
|
||||
* and private members.</td>
|
||||
* <td>This is dangerous in that information (possibly confidential) and
|
||||
* methods normally unavailable would be accessible to malicious code.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>newProxyInPackage.{package name}</td>
|
||||
* <td>ability to create a proxy instance in the specified package of which
|
||||
* the non-public interface that the proxy class implements.</td>
|
||||
* <td>This gives code access to classes in packages to which it normally
|
||||
* does not have access and the dynamic proxy class is in the system
|
||||
* protection domain. Malicious code may use these classes to
|
||||
* help in its attempt to compromise security in the system.</td>
|
||||
* </tr>
|
||||
*
|
||||
* </table>
|
||||
*
|
||||
* @see java.security.Permission
|
||||
* @see java.security.BasicPermission
|
||||
* @see AccessibleObject
|
||||
* @see Field#get
|
||||
* @see Field#set
|
||||
* @see Method#invoke
|
||||
* @see Constructor#newInstance
|
||||
* @see Proxy#newProxyInstance
|
||||
*
|
||||
* @since 1.2
|
||||
*/
|
||||
public final
|
||||
class ReflectPermission extends java.security.BasicPermission {
|
||||
|
||||
private static final long serialVersionUID = 7412737110241507485L;
|
||||
|
||||
/**
|
||||
* Constructs a ReflectPermission with the specified name.
|
||||
*
|
||||
* @param name the name of the ReflectPermission
|
||||
*
|
||||
* @throws NullPointerException if {@code name} is {@code null}.
|
||||
* @throws IllegalArgumentException if {@code name} is empty.
|
||||
*/
|
||||
public ReflectPermission(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a ReflectPermission with the specified name and actions.
|
||||
* The actions should be null; they are ignored.
|
||||
*
|
||||
* @param name the name of the ReflectPermission
|
||||
*
|
||||
* @param actions should be null
|
||||
*
|
||||
* @throws NullPointerException if {@code name} is {@code null}.
|
||||
* @throws IllegalArgumentException if {@code name} is empty.
|
||||
*/
|
||||
public ReflectPermission(String name, String actions) {
|
||||
super(name, actions);
|
||||
}
|
||||
|
||||
}
|
||||
48
jdkSrc/jdk8/java/lang/reflect/Type.java
Normal file
48
jdkSrc/jdk8/java/lang/reflect/Type.java
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang.reflect;
|
||||
|
||||
/**
|
||||
* Type is the common superinterface for all types in the Java
|
||||
* programming language. These include raw types, parameterized types,
|
||||
* array types, type variables and primitive types.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public interface Type {
|
||||
/**
|
||||
* Returns a string describing this type, including information
|
||||
* about any type parameters.
|
||||
*
|
||||
* @implSpec The default implementation calls {@code toString}.
|
||||
*
|
||||
* @return a string describing this type
|
||||
* @since 1.8
|
||||
*/
|
||||
default String getTypeName() {
|
||||
return toString();
|
||||
}
|
||||
}
|
||||
102
jdkSrc/jdk8/java/lang/reflect/TypeVariable.java
Normal file
102
jdkSrc/jdk8/java/lang/reflect/TypeVariable.java
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang.reflect;
|
||||
|
||||
/**
|
||||
* TypeVariable is the common superinterface for type variables of kinds.
|
||||
* A type variable is created the first time it is needed by a reflective
|
||||
* method, as specified in this package. If a type variable t is referenced
|
||||
* by a type (i.e, class, interface or annotation type) T, and T is declared
|
||||
* by the nth enclosing class of T (see JLS 8.1.2), then the creation of t
|
||||
* requires the resolution (see JVMS 5) of the ith enclosing class of T,
|
||||
* for i = 0 to n, inclusive. Creating a type variable must not cause the
|
||||
* creation of its bounds. Repeated creation of a type variable has no effect.
|
||||
*
|
||||
* <p>Multiple objects may be instantiated at run-time to
|
||||
* represent a given type variable. Even though a type variable is
|
||||
* created only once, this does not imply any requirement to cache
|
||||
* instances representing the type variable. However, all instances
|
||||
* representing a type variable must be equal() to each other.
|
||||
* As a consequence, users of type variables must not rely on the identity
|
||||
* of instances of classes implementing this interface.
|
||||
*
|
||||
* @param <D> the type of generic declaration that declared the
|
||||
* underlying type variable.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public interface TypeVariable<D extends GenericDeclaration> extends Type, AnnotatedElement {
|
||||
/**
|
||||
* Returns an array of {@code Type} objects representing the
|
||||
* upper bound(s) of this type variable. Note that if no upper bound is
|
||||
* explicitly declared, the upper bound is {@code Object}.
|
||||
*
|
||||
* <p>For each upper bound B: <ul> <li>if B is a parameterized
|
||||
* type or a type variable, it is created, (see {@link
|
||||
* java.lang.reflect.ParameterizedType ParameterizedType} for the
|
||||
* details of the creation process for parameterized types).
|
||||
* <li>Otherwise, B is resolved. </ul>
|
||||
*
|
||||
* @throws TypeNotPresentException if any of the
|
||||
* bounds refers to a non-existent type declaration
|
||||
* @throws MalformedParameterizedTypeException if any of the
|
||||
* bounds refer to a parameterized type that cannot be instantiated
|
||||
* for any reason
|
||||
* @return an array of {@code Type}s representing the upper
|
||||
* bound(s) of this type variable
|
||||
*/
|
||||
Type[] getBounds();
|
||||
|
||||
/**
|
||||
* Returns the {@code GenericDeclaration} object representing the
|
||||
* generic declaration declared this type variable.
|
||||
*
|
||||
* @return the generic declaration declared for this type variable.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
D getGenericDeclaration();
|
||||
|
||||
/**
|
||||
* Returns the name of this type variable, as it occurs in the source code.
|
||||
*
|
||||
* @return the name of this type variable, as it appears in the source code
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Returns an array of AnnotatedType objects that represent the use of
|
||||
* types to denote the upper bounds of the type parameter represented by
|
||||
* this TypeVariable. The order of the objects in the array corresponds to
|
||||
* the order of the bounds in the declaration of the type parameter.
|
||||
*
|
||||
* Returns an array of length 0 if the type parameter declares no bounds.
|
||||
*
|
||||
* @return an array of objects representing the upper bounds of the type variable
|
||||
* @since 1.8
|
||||
*/
|
||||
AnnotatedType[] getAnnotatedBounds();
|
||||
}
|
||||
119
jdkSrc/jdk8/java/lang/reflect/UndeclaredThrowableException.java
Normal file
119
jdkSrc/jdk8/java/lang/reflect/UndeclaredThrowableException.java
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2006, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang.reflect;
|
||||
|
||||
/**
|
||||
* Thrown by a method invocation on a proxy instance if its invocation
|
||||
* handler's {@link InvocationHandler#invoke invoke} method throws a
|
||||
* checked exception (a {@code Throwable} that is not assignable
|
||||
* to {@code RuntimeException} or {@code Error}) that
|
||||
* is not assignable to any of the exception types declared in the
|
||||
* {@code throws} clause of the method that was invoked on the
|
||||
* proxy instance and dispatched to the invocation handler.
|
||||
*
|
||||
* <p>An {@code UndeclaredThrowableException} instance contains
|
||||
* the undeclared checked exception that was thrown by the invocation
|
||||
* handler, and it can be retrieved with the
|
||||
* {@code getUndeclaredThrowable()} method.
|
||||
* {@code UndeclaredThrowableException} extends
|
||||
* {@code RuntimeException}, so it is an unchecked exception
|
||||
* that wraps a checked exception.
|
||||
*
|
||||
* <p>As of release 1.4, this exception has been retrofitted to
|
||||
* conform to the general purpose exception-chaining mechanism. The
|
||||
* "undeclared checked exception that was thrown by the invocation
|
||||
* handler" that may be provided at construction time and accessed via
|
||||
* the {@link #getUndeclaredThrowable()} method is now known as the
|
||||
* <i>cause</i>, and may be accessed via the {@link
|
||||
* Throwable#getCause()} method, as well as the aforementioned "legacy
|
||||
* method."
|
||||
*
|
||||
* @author Peter Jones
|
||||
* @see InvocationHandler
|
||||
* @since 1.3
|
||||
*/
|
||||
public class UndeclaredThrowableException extends RuntimeException {
|
||||
static final long serialVersionUID = 330127114055056639L;
|
||||
|
||||
/**
|
||||
* the undeclared checked exception that was thrown
|
||||
* @serial
|
||||
*/
|
||||
private Throwable undeclaredThrowable;
|
||||
|
||||
/**
|
||||
* Constructs an {@code UndeclaredThrowableException} with the
|
||||
* specified {@code Throwable}.
|
||||
*
|
||||
* @param undeclaredThrowable the undeclared checked exception
|
||||
* that was thrown
|
||||
*/
|
||||
public UndeclaredThrowableException(Throwable undeclaredThrowable) {
|
||||
super((Throwable) null); // Disallow initCause
|
||||
this.undeclaredThrowable = undeclaredThrowable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an {@code UndeclaredThrowableException} with the
|
||||
* specified {@code Throwable} and a detail message.
|
||||
*
|
||||
* @param undeclaredThrowable the undeclared checked exception
|
||||
* that was thrown
|
||||
* @param s the detail message
|
||||
*/
|
||||
public UndeclaredThrowableException(Throwable undeclaredThrowable,
|
||||
String s)
|
||||
{
|
||||
super(s, null); // Disallow initCause
|
||||
this.undeclaredThrowable = undeclaredThrowable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@code Throwable} instance wrapped in this
|
||||
* {@code UndeclaredThrowableException}, which may be {@code null}.
|
||||
*
|
||||
* <p>This method predates the general-purpose exception chaining facility.
|
||||
* The {@link Throwable#getCause()} method is now the preferred means of
|
||||
* obtaining this information.
|
||||
*
|
||||
* @return the undeclared checked exception that was thrown
|
||||
*/
|
||||
public Throwable getUndeclaredThrowable() {
|
||||
return undeclaredThrowable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the cause of this exception (the {@code Throwable}
|
||||
* instance wrapped in this {@code UndeclaredThrowableException},
|
||||
* which may be {@code null}).
|
||||
*
|
||||
* @return the cause of this exception.
|
||||
* @since 1.4
|
||||
*/
|
||||
public Throwable getCause() {
|
||||
return undeclaredThrowable;
|
||||
}
|
||||
}
|
||||
379
jdkSrc/jdk8/java/lang/reflect/WeakCache.java
Normal file
379
jdkSrc/jdk8/java/lang/reflect/WeakCache.java
Normal file
@@ -0,0 +1,379 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package java.lang.reflect;
|
||||
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* Cache mapping pairs of {@code (key, sub-key) -> value}. Keys and values are
|
||||
* weakly but sub-keys are strongly referenced. Keys are passed directly to
|
||||
* {@link #get} method which also takes a {@code parameter}. Sub-keys are
|
||||
* calculated from keys and parameters using the {@code subKeyFactory} function
|
||||
* passed to the constructor. Values are calculated from keys and parameters
|
||||
* using the {@code valueFactory} function passed to the constructor.
|
||||
* Keys can be {@code null} and are compared by identity while sub-keys returned by
|
||||
* {@code subKeyFactory} or values returned by {@code valueFactory}
|
||||
* can not be null. Sub-keys are compared using their {@link #equals} method.
|
||||
* Entries are expunged from cache lazily on each invocation to {@link #get},
|
||||
* {@link #containsValue} or {@link #size} methods when the WeakReferences to
|
||||
* keys are cleared. Cleared WeakReferences to individual values don't cause
|
||||
* expunging, but such entries are logically treated as non-existent and
|
||||
* trigger re-evaluation of {@code valueFactory} on request for their
|
||||
* key/subKey.
|
||||
*
|
||||
* @author Peter Levart
|
||||
* @param <K> type of keys
|
||||
* @param <P> type of parameters
|
||||
* @param <V> type of values
|
||||
*/
|
||||
final class WeakCache<K, P, V> {
|
||||
|
||||
private final ReferenceQueue<K> refQueue
|
||||
= new ReferenceQueue<>();
|
||||
// the key type is Object for supporting null key
|
||||
private final ConcurrentMap<Object, ConcurrentMap<Object, Supplier<V>>> map
|
||||
= new ConcurrentHashMap<>();
|
||||
private final ConcurrentMap<Supplier<V>, Boolean> reverseMap
|
||||
= new ConcurrentHashMap<>();
|
||||
private final BiFunction<K, P, ?> subKeyFactory;
|
||||
private final BiFunction<K, P, V> valueFactory;
|
||||
|
||||
/**
|
||||
* Construct an instance of {@code WeakCache}
|
||||
*
|
||||
* @param subKeyFactory a function mapping a pair of
|
||||
* {@code (key, parameter) -> sub-key}
|
||||
* @param valueFactory a function mapping a pair of
|
||||
* {@code (key, parameter) -> value}
|
||||
* @throws NullPointerException if {@code subKeyFactory} or
|
||||
* {@code valueFactory} is null.
|
||||
*/
|
||||
public WeakCache(BiFunction<K, P, ?> subKeyFactory,
|
||||
BiFunction<K, P, V> valueFactory) {
|
||||
this.subKeyFactory = Objects.requireNonNull(subKeyFactory);
|
||||
this.valueFactory = Objects.requireNonNull(valueFactory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Look-up the value through the cache. This always evaluates the
|
||||
* {@code subKeyFactory} function and optionally evaluates
|
||||
* {@code valueFactory} function if there is no entry in the cache for given
|
||||
* pair of (key, subKey) or the entry has already been cleared.
|
||||
*
|
||||
* @param key possibly null key
|
||||
* @param parameter parameter used together with key to create sub-key and
|
||||
* value (should not be null)
|
||||
* @return the cached value (never null)
|
||||
* @throws NullPointerException if {@code parameter} passed in or
|
||||
* {@code sub-key} calculated by
|
||||
* {@code subKeyFactory} or {@code value}
|
||||
* calculated by {@code valueFactory} is null.
|
||||
*/
|
||||
public V get(K key, P parameter) {
|
||||
Objects.requireNonNull(parameter);
|
||||
|
||||
expungeStaleEntries();
|
||||
|
||||
Object cacheKey = CacheKey.valueOf(key, refQueue);
|
||||
|
||||
// lazily install the 2nd level valuesMap for the particular cacheKey
|
||||
ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey);
|
||||
if (valuesMap == null) {
|
||||
ConcurrentMap<Object, Supplier<V>> oldValuesMap
|
||||
= map.putIfAbsent(cacheKey,
|
||||
valuesMap = new ConcurrentHashMap<>());
|
||||
if (oldValuesMap != null) {
|
||||
valuesMap = oldValuesMap;
|
||||
}
|
||||
}
|
||||
|
||||
// create subKey and retrieve the possible Supplier<V> stored by that
|
||||
// subKey from valuesMap
|
||||
Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
|
||||
Supplier<V> supplier = valuesMap.get(subKey);
|
||||
Factory factory = null;
|
||||
|
||||
while (true) {
|
||||
if (supplier != null) {
|
||||
// supplier might be a Factory or a CacheValue<V> instance
|
||||
V value = supplier.get();
|
||||
if (value != null) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
// else no supplier in cache
|
||||
// or a supplier that returned null (could be a cleared CacheValue
|
||||
// or a Factory that wasn't successful in installing the CacheValue)
|
||||
|
||||
// lazily construct a Factory
|
||||
if (factory == null) {
|
||||
factory = new Factory(key, parameter, subKey, valuesMap);
|
||||
}
|
||||
|
||||
if (supplier == null) {
|
||||
supplier = valuesMap.putIfAbsent(subKey, factory);
|
||||
if (supplier == null) {
|
||||
// successfully installed Factory
|
||||
supplier = factory;
|
||||
}
|
||||
// else retry with winning supplier
|
||||
} else {
|
||||
if (valuesMap.replace(subKey, supplier, factory)) {
|
||||
// successfully replaced
|
||||
// cleared CacheEntry / unsuccessful Factory
|
||||
// with our Factory
|
||||
supplier = factory;
|
||||
} else {
|
||||
// retry with current supplier
|
||||
supplier = valuesMap.get(subKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the specified non-null value is already present in this
|
||||
* {@code WeakCache}. The check is made using identity comparison regardless
|
||||
* of whether value's class overrides {@link Object#equals} or not.
|
||||
*
|
||||
* @param value the non-null value to check
|
||||
* @return true if given {@code value} is already cached
|
||||
* @throws NullPointerException if value is null
|
||||
*/
|
||||
public boolean containsValue(V value) {
|
||||
Objects.requireNonNull(value);
|
||||
|
||||
expungeStaleEntries();
|
||||
return reverseMap.containsKey(new LookupValue<>(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current number of cached entries that
|
||||
* can decrease over time when keys/values are GC-ed.
|
||||
*/
|
||||
public int size() {
|
||||
expungeStaleEntries();
|
||||
return reverseMap.size();
|
||||
}
|
||||
|
||||
private void expungeStaleEntries() {
|
||||
CacheKey<K> cacheKey;
|
||||
while ((cacheKey = (CacheKey<K>)refQueue.poll()) != null) {
|
||||
cacheKey.expungeFrom(map, reverseMap);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A factory {@link Supplier} that implements the lazy synchronized
|
||||
* construction of the value and installment of it into the cache.
|
||||
*/
|
||||
private final class Factory implements Supplier<V> {
|
||||
|
||||
private final K key;
|
||||
private final P parameter;
|
||||
private final Object subKey;
|
||||
private final ConcurrentMap<Object, Supplier<V>> valuesMap;
|
||||
|
||||
Factory(K key, P parameter, Object subKey,
|
||||
ConcurrentMap<Object, Supplier<V>> valuesMap) {
|
||||
this.key = key;
|
||||
this.parameter = parameter;
|
||||
this.subKey = subKey;
|
||||
this.valuesMap = valuesMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized V get() { // serialize access
|
||||
// re-check
|
||||
Supplier<V> supplier = valuesMap.get(subKey);
|
||||
if (supplier != this) {
|
||||
// something changed while we were waiting:
|
||||
// might be that we were replaced by a CacheValue
|
||||
// or were removed because of failure ->
|
||||
// return null to signal WeakCache.get() to retry
|
||||
// the loop
|
||||
return null;
|
||||
}
|
||||
// else still us (supplier == this)
|
||||
|
||||
// create new value
|
||||
V value = null;
|
||||
try {
|
||||
value = Objects.requireNonNull(valueFactory.apply(key, parameter));
|
||||
} finally {
|
||||
if (value == null) { // remove us on failure
|
||||
valuesMap.remove(subKey, this);
|
||||
}
|
||||
}
|
||||
// the only path to reach here is with non-null value
|
||||
assert value != null;
|
||||
|
||||
// wrap value with CacheValue (WeakReference)
|
||||
CacheValue<V> cacheValue = new CacheValue<>(value);
|
||||
|
||||
// put into reverseMap
|
||||
reverseMap.put(cacheValue, Boolean.TRUE);
|
||||
|
||||
// try replacing us with CacheValue (this should always succeed)
|
||||
if (!valuesMap.replace(subKey, this, cacheValue)) {
|
||||
throw new AssertionError("Should not reach here");
|
||||
}
|
||||
|
||||
// successfully replaced us with new CacheValue -> return the value
|
||||
// wrapped by it
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Common type of value suppliers that are holding a referent.
|
||||
* The {@link #equals} and {@link #hashCode} of implementations is defined
|
||||
* to compare the referent by identity.
|
||||
*/
|
||||
private interface Value<V> extends Supplier<V> {}
|
||||
|
||||
/**
|
||||
* An optimized {@link Value} used to look-up the value in
|
||||
* {@link WeakCache#containsValue} method so that we are not
|
||||
* constructing the whole {@link CacheValue} just to look-up the referent.
|
||||
*/
|
||||
private static final class LookupValue<V> implements Value<V> {
|
||||
private final V value;
|
||||
|
||||
LookupValue(V value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public V get() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return System.identityHashCode(value); // compare by identity
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj == this ||
|
||||
obj instanceof Value &&
|
||||
this.value == ((Value<?>) obj).get(); // compare by identity
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@link Value} that weakly references the referent.
|
||||
*/
|
||||
private static final class CacheValue<V>
|
||||
extends WeakReference<V> implements Value<V>
|
||||
{
|
||||
private final int hash;
|
||||
|
||||
CacheValue(V value) {
|
||||
super(value);
|
||||
this.hash = System.identityHashCode(value); // compare by identity
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
V value;
|
||||
return obj == this ||
|
||||
obj instanceof Value &&
|
||||
// cleared CacheValue is only equal to itself
|
||||
(value = get()) != null &&
|
||||
value == ((Value<?>) obj).get(); // compare by identity
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* CacheKey containing a weakly referenced {@code key}. It registers
|
||||
* itself with the {@code refQueue} so that it can be used to expunge
|
||||
* the entry when the {@link WeakReference} is cleared.
|
||||
*/
|
||||
private static final class CacheKey<K> extends WeakReference<K> {
|
||||
|
||||
// a replacement for null keys
|
||||
private static final Object NULL_KEY = new Object();
|
||||
|
||||
static <K> Object valueOf(K key, ReferenceQueue<K> refQueue) {
|
||||
return key == null
|
||||
// null key means we can't weakly reference it,
|
||||
// so we use a NULL_KEY singleton as cache key
|
||||
? NULL_KEY
|
||||
// non-null key requires wrapping with a WeakReference
|
||||
: new CacheKey<>(key, refQueue);
|
||||
}
|
||||
|
||||
private final int hash;
|
||||
|
||||
private CacheKey(K key, ReferenceQueue<K> refQueue) {
|
||||
super(key, refQueue);
|
||||
this.hash = System.identityHashCode(key); // compare by identity
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
K key;
|
||||
return obj == this ||
|
||||
obj != null &&
|
||||
obj.getClass() == this.getClass() &&
|
||||
// cleared CacheKey is only equal to itself
|
||||
(key = this.get()) != null &&
|
||||
// compare key by identity
|
||||
key == ((CacheKey<K>) obj).get();
|
||||
}
|
||||
|
||||
void expungeFrom(ConcurrentMap<?, ? extends ConcurrentMap<?, ?>> map,
|
||||
ConcurrentMap<?, Boolean> reverseMap) {
|
||||
// removing just by key is always safe here because after a CacheKey
|
||||
// is cleared and enqueue-ed it is only equal to itself
|
||||
// (see equals method)...
|
||||
ConcurrentMap<?, ?> valuesMap = map.remove(this);
|
||||
// remove also from reverseMap if needed
|
||||
if (valuesMap != null) {
|
||||
for (Object cacheValue : valuesMap.values()) {
|
||||
reverseMap.remove(cacheValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
83
jdkSrc/jdk8/java/lang/reflect/WildcardType.java
Normal file
83
jdkSrc/jdk8/java/lang/reflect/WildcardType.java
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang.reflect;
|
||||
|
||||
/**
|
||||
* WildcardType represents a wildcard type expression, such as
|
||||
* {@code ?}, {@code ? extends Number}, or {@code ? super Integer}.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public interface WildcardType extends Type {
|
||||
/**
|
||||
* Returns an array of {@code Type} objects representing the upper
|
||||
* bound(s) of this type variable. Note that if no upper bound is
|
||||
* explicitly declared, the upper bound is {@code Object}.
|
||||
*
|
||||
* <p>For each upper bound B :
|
||||
* <ul>
|
||||
* <li>if B is a parameterized type or a type variable, it is created,
|
||||
* (see {@link java.lang.reflect.ParameterizedType ParameterizedType}
|
||||
* for the details of the creation process for parameterized types).
|
||||
* <li>Otherwise, B is resolved.
|
||||
* </ul>
|
||||
*
|
||||
* @return an array of Types representing the upper bound(s) of this
|
||||
* type variable
|
||||
* @throws TypeNotPresentException if any of the
|
||||
* bounds refers to a non-existent type declaration
|
||||
* @throws MalformedParameterizedTypeException if any of the
|
||||
* bounds refer to a parameterized type that cannot be instantiated
|
||||
* for any reason
|
||||
*/
|
||||
Type[] getUpperBounds();
|
||||
|
||||
/**
|
||||
* Returns an array of {@code Type} objects representing the
|
||||
* lower bound(s) of this type variable. Note that if no lower bound is
|
||||
* explicitly declared, the lower bound is the type of {@code null}.
|
||||
* In this case, a zero length array is returned.
|
||||
*
|
||||
* <p>For each lower bound B :
|
||||
* <ul>
|
||||
* <li>if B is a parameterized type or a type variable, it is created,
|
||||
* (see {@link java.lang.reflect.ParameterizedType ParameterizedType}
|
||||
* for the details of the creation process for parameterized types).
|
||||
* <li>Otherwise, B is resolved.
|
||||
* </ul>
|
||||
*
|
||||
* @return an array of Types representing the lower bound(s) of this
|
||||
* type variable
|
||||
* @throws TypeNotPresentException if any of the
|
||||
* bounds refers to a non-existent type declaration
|
||||
* @throws MalformedParameterizedTypeException if any of the
|
||||
* bounds refer to a parameterized type that cannot be instantiated
|
||||
* for any reason
|
||||
*/
|
||||
Type[] getLowerBounds();
|
||||
// one or many? Up to language spec; currently only one, but this API
|
||||
// allows for generalization.
|
||||
}
|
||||
49
jdkSrc/jdk8/java/lang/reflect/package-info.java
Normal file
49
jdkSrc/jdk8/java/lang/reflect/package-info.java
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provides classes and interfaces for obtaining reflective
|
||||
* information about classes and objects. Reflection allows
|
||||
* programmatic access to information about the fields, methods and
|
||||
* constructors of loaded classes, and the use of reflected fields,
|
||||
* methods, and constructors to operate on their underlying
|
||||
* counterparts, within security restrictions.
|
||||
*
|
||||
* <p>{@code AccessibleObject} allows suppression of access checks if
|
||||
* the necessary {@code ReflectPermission} is available.
|
||||
*
|
||||
* <p>{@code Array} provides static methods to dynamically create and
|
||||
* access arrays.
|
||||
*
|
||||
* <p>Classes in this package, along with {@code java.lang.Class}
|
||||
* accommodate applications such as debuggers, interpreters, object
|
||||
* inspectors, class browsers, and services such as Object
|
||||
* Serialization and JavaBeans that need access to either the public
|
||||
* members of a target object (based on its runtime class) or the
|
||||
* members declared by a given class.
|
||||
*
|
||||
* @since JDK1.1
|
||||
*/
|
||||
package java.lang.reflect;
|
||||
Reference in New Issue
Block a user