mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8187443: Forest Consolidation: Move files to unified layout
Reviewed-by: darcy, ihse
This commit is contained in:
parent
270fe13182
commit
3789983e89
56923 changed files with 3 additions and 15727 deletions
|
@ -0,0 +1,674 @@
|
|||
/*
|
||||
* Copyright (c) 1997, 2017, 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.security.AccessController;
|
||||
|
||||
import jdk.internal.misc.VM;
|
||||
import jdk.internal.module.IllegalAccessLogger;
|
||||
import jdk.internal.reflect.CallerSensitive;
|
||||
import jdk.internal.reflect.Reflection;
|
||||
import jdk.internal.reflect.ReflectionFactory;
|
||||
import sun.security.action.GetPropertyAction;
|
||||
|
||||
/**
|
||||
* The {@code AccessibleObject} class is the base class for {@code Field},
|
||||
* {@code Method}, and {@code Constructor} objects (known as <em>reflected
|
||||
* objects</em>). It provides the ability to flag a reflected object as
|
||||
* suppressing checks for Java language access control when it is used. This
|
||||
* 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> Java language access control prevents use of private members outside
|
||||
* their class; package access members outside their package; protected members
|
||||
* outside their package or subclasses; and public members outside their
|
||||
* module unless they are declared in an {@link Module#isExported(String,Module)
|
||||
* exported} package and the user {@link Module#canRead reads} their module. By
|
||||
* default, Java language access control is enforced (with one variation) when
|
||||
* {@code Field}s, {@code Method}s, or {@code Constructor}s are used to get or
|
||||
* set fields, to invoke methods, or to create and initialize new instances of
|
||||
* classes, respectively. Every reflected object checks that the code using it
|
||||
* is in an appropriate class, package, or module. </p>
|
||||
*
|
||||
* <p> The one variation from Java language access control is that the checks
|
||||
* by reflected objects assume readability. That is, the module containing
|
||||
* the use of a reflected object is assumed to read the module in which
|
||||
* the underlying field, method, or constructor is declared. </p>
|
||||
*
|
||||
* <p> Whether the checks for Java language access control can be suppressed
|
||||
* (and thus, whether access can be enabled) depends on whether the reflected
|
||||
* object corresponds to a member in an exported or open package
|
||||
* (see {@link #setAccessible(boolean)}). </p>
|
||||
*
|
||||
* @jls 6.6 Access Control
|
||||
* @since 1.2
|
||||
* @revised 9
|
||||
* @spec JPMS
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
private static final java.security.Permission ACCESS_PERMISSION =
|
||||
new ReflectPermission("suppressAccessChecks");
|
||||
|
||||
static void checkPermission() {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) sm.checkPermission(ACCESS_PERMISSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to set the {@code accessible} flag for an
|
||||
* array of reflected objects with a single security check (for efficiency).
|
||||
*
|
||||
* <p> This method may be used to enable access to all reflected objects in
|
||||
* the array when access to each reflected object can be enabled as
|
||||
* specified by {@link #setAccessible(boolean) setAccessible(boolean)}. </p>
|
||||
*
|
||||
* <p>If there is a security manager, its
|
||||
* {@code checkPermission} method is first called with a
|
||||
* {@code ReflectPermission("suppressAccessChecks")} permission.
|
||||
*
|
||||
* <p>A {@code SecurityException} is also thrown if any of the elements of
|
||||
* the input {@code array} is a {@link java.lang.reflect.Constructor}
|
||||
* object for the class {@code java.lang.Class} and {@code flag} is true.
|
||||
*
|
||||
* @param array the array of AccessibleObjects
|
||||
* @param flag the new value for the {@code accessible} flag
|
||||
* in each object
|
||||
* @throws InaccessibleObjectException if access cannot be enabled for all
|
||||
* objects in the array
|
||||
* @throws SecurityException if the request is denied by the security manager
|
||||
* or an element in the array is a constructor for {@code
|
||||
* java.lang.Class}
|
||||
* @see SecurityManager#checkPermission
|
||||
* @see ReflectPermission
|
||||
* @revised 9
|
||||
* @spec JPMS
|
||||
*/
|
||||
@CallerSensitive
|
||||
public static void setAccessible(AccessibleObject[] array, boolean flag) {
|
||||
checkPermission();
|
||||
if (flag) {
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
array = array.clone();
|
||||
for (AccessibleObject ao : array) {
|
||||
ao.checkCanSetAccessible(caller);
|
||||
}
|
||||
}
|
||||
for (AccessibleObject ao : array) {
|
||||
ao.setAccessible0(flag);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@code accessible} flag for this reflected object to
|
||||
* the indicated boolean value. A value of {@code true} indicates that
|
||||
* the reflected object should suppress checks for Java language access
|
||||
* control when it is used. A value of {@code false} indicates that
|
||||
* the reflected object should enforce checks for Java language access
|
||||
* control when it is used, with the variation noted in the class description.
|
||||
*
|
||||
* <p> This method may be used by a caller in class {@code C} to enable
|
||||
* access to a {@link Member member} of {@link Member#getDeclaringClass()
|
||||
* declaring class} {@code D} if any of the following hold: </p>
|
||||
*
|
||||
* <ul>
|
||||
* <li> {@code C} and {@code D} are in the same module. </li>
|
||||
*
|
||||
* <li> The member is {@code public} and {@code D} is {@code public} in
|
||||
* a package that the module containing {@code D} {@link
|
||||
* Module#isExported(String,Module) exports} to at least the module
|
||||
* containing {@code C}. </li>
|
||||
*
|
||||
* <li> The member is {@code protected} {@code static}, {@code D} is
|
||||
* {@code public} in a package that the module containing {@code D}
|
||||
* exports to at least the module containing {@code C}, and {@code C}
|
||||
* is a subclass of {@code D}. </li>
|
||||
*
|
||||
* <li> {@code D} is in a package that the module containing {@code D}
|
||||
* {@link Module#isOpen(String,Module) opens} to at least the module
|
||||
* containing {@code C}.
|
||||
* All packages in unnamed and open modules are open to all modules and
|
||||
* so this method always succeeds when {@code D} is in an unnamed or
|
||||
* open module. </li>
|
||||
* </ul>
|
||||
*
|
||||
* <p> This method cannot be used to enable access to private members,
|
||||
* members with default (package) access, protected instance members, or
|
||||
* protected constructors when the declaring class is in a different module
|
||||
* to the caller and the package containing the declaring class is not open
|
||||
* to the caller's module. </p>
|
||||
*
|
||||
* <p> If there is a security manager, its
|
||||
* {@code checkPermission} method is first called with a
|
||||
* {@code ReflectPermission("suppressAccessChecks")} permission.
|
||||
*
|
||||
* @param flag the new value for the {@code accessible} flag
|
||||
* @throws InaccessibleObjectException if access cannot be enabled
|
||||
* @throws SecurityException if the request is denied by the security manager
|
||||
* @see #trySetAccessible
|
||||
* @see java.lang.invoke.MethodHandles#privateLookupIn
|
||||
* @revised 9
|
||||
* @spec JPMS
|
||||
*/
|
||||
public void setAccessible(boolean flag) {
|
||||
AccessibleObject.checkPermission();
|
||||
setAccessible0(flag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the accessible flag and returns the new value
|
||||
*/
|
||||
boolean setAccessible0(boolean flag) {
|
||||
this.override = flag;
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@code accessible} flag for this reflected object to {@code true}
|
||||
* if possible. This method sets the {@code accessible} flag, as if by
|
||||
* invoking {@link #setAccessible(boolean) setAccessible(true)}, and returns
|
||||
* the possibly-updated value for the {@code accessible} flag. If access
|
||||
* cannot be enabled, i.e. the checks or Java language access control cannot
|
||||
* be suppressed, this method returns {@code false} (as opposed to {@code
|
||||
* setAccessible(true)} throwing {@code InaccessibleObjectException} when
|
||||
* it fails).
|
||||
*
|
||||
* <p> This method is a no-op if the {@code accessible} flag for
|
||||
* this reflected object is {@code true}.
|
||||
*
|
||||
* <p> For example, a caller can invoke {@code trySetAccessible}
|
||||
* on a {@code Method} object for a private instance method
|
||||
* {@code p.T::privateMethod} to suppress the checks for Java language access
|
||||
* control when the {@code Method} is invoked.
|
||||
* If {@code p.T} class is in a different module to the caller and
|
||||
* package {@code p} is open to at least the caller's module,
|
||||
* the code below successfully sets the {@code accessible} flag
|
||||
* to {@code true}.
|
||||
*
|
||||
* <pre>
|
||||
* {@code
|
||||
* p.T obj = ....; // instance of p.T
|
||||
* :
|
||||
* Method m = p.T.class.getDeclaredMethod("privateMethod");
|
||||
* if (m.trySetAccessible()) {
|
||||
* m.invoke(obj);
|
||||
* } else {
|
||||
* // package p is not opened to the caller to access private member of T
|
||||
* ...
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* <p> If there is a security manager, its {@code checkPermission} method
|
||||
* is first called with a {@code ReflectPermission("suppressAccessChecks")}
|
||||
* permission. </p>
|
||||
*
|
||||
* @return {@code true} if the {@code accessible} flag is set to {@code true};
|
||||
* {@code false} if access cannot be enabled.
|
||||
* @throws SecurityException if the request is denied by the security manager
|
||||
*
|
||||
* @since 9
|
||||
* @spec JPMS
|
||||
* @see java.lang.invoke.MethodHandles#privateLookupIn
|
||||
*/
|
||||
@CallerSensitive
|
||||
public final boolean trySetAccessible() {
|
||||
AccessibleObject.checkPermission();
|
||||
|
||||
if (override == true) return true;
|
||||
|
||||
// if it's not a Constructor, Method, Field then no access check
|
||||
if (!Member.class.isInstance(this)) {
|
||||
return setAccessible0(true);
|
||||
}
|
||||
|
||||
// does not allow to suppress access check for Class's constructor
|
||||
Class<?> declaringClass = ((Member) this).getDeclaringClass();
|
||||
if (declaringClass == Class.class && this instanceof Constructor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (checkCanSetAccessible(Reflection.getCallerClass(),
|
||||
declaringClass,
|
||||
false)) {
|
||||
return setAccessible0(true);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If the given AccessibleObject is a {@code Constructor}, {@code Method}
|
||||
* or {@code Field} then checks that its declaring class is in a package
|
||||
* that can be accessed by the given caller of setAccessible.
|
||||
*/
|
||||
void checkCanSetAccessible(Class<?> caller) {
|
||||
// do nothing, needs to be overridden by Constructor, Method, Field
|
||||
}
|
||||
|
||||
|
||||
void checkCanSetAccessible(Class<?> caller, Class<?> declaringClass) {
|
||||
checkCanSetAccessible(caller, declaringClass, true);
|
||||
}
|
||||
|
||||
private boolean checkCanSetAccessible(Class<?> caller,
|
||||
Class<?> declaringClass,
|
||||
boolean throwExceptionIfDenied) {
|
||||
Module callerModule = caller.getModule();
|
||||
Module declaringModule = declaringClass.getModule();
|
||||
|
||||
if (callerModule == declaringModule) return true;
|
||||
if (callerModule == Object.class.getModule()) return true;
|
||||
if (!declaringModule.isNamed()) return true;
|
||||
|
||||
String pn = declaringClass.getPackageName();
|
||||
int modifiers;
|
||||
if (this instanceof Executable) {
|
||||
modifiers = ((Executable) this).getModifiers();
|
||||
} else {
|
||||
modifiers = ((Field) this).getModifiers();
|
||||
}
|
||||
|
||||
// class is public and package is exported to caller
|
||||
boolean isClassPublic = Modifier.isPublic(declaringClass.getModifiers());
|
||||
if (isClassPublic && declaringModule.isExported(pn, callerModule)) {
|
||||
// member is public
|
||||
if (Modifier.isPublic(modifiers)) {
|
||||
logIfExportedForIllegalAccess(caller, declaringClass);
|
||||
return true;
|
||||
}
|
||||
|
||||
// member is protected-static
|
||||
if (Modifier.isProtected(modifiers)
|
||||
&& Modifier.isStatic(modifiers)
|
||||
&& isSubclassOf(caller, declaringClass)) {
|
||||
logIfExportedForIllegalAccess(caller, declaringClass);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// package is open to caller
|
||||
if (declaringModule.isOpen(pn, callerModule)) {
|
||||
logIfOpenedForIllegalAccess(caller, declaringClass);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (throwExceptionIfDenied) {
|
||||
// not accessible
|
||||
String msg = "Unable to make ";
|
||||
if (this instanceof Field)
|
||||
msg += "field ";
|
||||
msg += this + " accessible: " + declaringModule + " does not \"";
|
||||
if (isClassPublic && Modifier.isPublic(modifiers))
|
||||
msg += "exports";
|
||||
else
|
||||
msg += "opens";
|
||||
msg += " " + pn + "\" to " + callerModule;
|
||||
InaccessibleObjectException e = new InaccessibleObjectException(msg);
|
||||
if (printStackTraceWhenAccessFails()) {
|
||||
e.printStackTrace(System.err);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isSubclassOf(Class<?> queryClass, Class<?> ofClass) {
|
||||
while (queryClass != null) {
|
||||
if (queryClass == ofClass) {
|
||||
return true;
|
||||
}
|
||||
queryClass = queryClass.getSuperclass();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void logIfOpenedForIllegalAccess(Class<?> caller, Class<?> declaringClass) {
|
||||
Module callerModule = caller.getModule();
|
||||
Module targetModule = declaringClass.getModule();
|
||||
// callerModule is null during early startup
|
||||
if (callerModule != null && !callerModule.isNamed() && targetModule.isNamed()) {
|
||||
IllegalAccessLogger logger = IllegalAccessLogger.illegalAccessLogger();
|
||||
if (logger != null) {
|
||||
logger.logIfOpenedForIllegalAccess(caller, declaringClass, this::toShortString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void logIfExportedForIllegalAccess(Class<?> caller, Class<?> declaringClass) {
|
||||
Module callerModule = caller.getModule();
|
||||
Module targetModule = declaringClass.getModule();
|
||||
// callerModule is null during early startup
|
||||
if (callerModule != null && !callerModule.isNamed() && targetModule.isNamed()) {
|
||||
IllegalAccessLogger logger = IllegalAccessLogger.illegalAccessLogger();
|
||||
if (logger != null) {
|
||||
logger.logIfExportedForIllegalAccess(caller, declaringClass, this::toShortString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a short descriptive string to describe this object in log messages.
|
||||
*/
|
||||
String toShortString() {
|
||||
return toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of the {@code accessible} flag for this reflected object.
|
||||
*
|
||||
* @return the value of the object's {@code accessible} flag
|
||||
*
|
||||
* @deprecated
|
||||
* This method is deprecated because its name hints that it checks
|
||||
* if the reflected object is accessible when it actually indicates
|
||||
* if the checks for Java language access control are suppressed.
|
||||
* This method may return {@code false} on a reflected object that is
|
||||
* accessible to the caller. To test if this reflected object is accessible,
|
||||
* it should use {@link #canAccess(Object)}.
|
||||
*
|
||||
* @revised 9
|
||||
* @spec JPMS
|
||||
*/
|
||||
@Deprecated(since="9")
|
||||
public boolean isAccessible() {
|
||||
return override;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the caller can access this reflected object. If this reflected
|
||||
* object corresponds to an instance method or field then this method tests
|
||||
* if the caller can access the given {@code obj} with the reflected object.
|
||||
* For instance methods or fields then the {@code obj} argument must be an
|
||||
* instance of the {@link Member#getDeclaringClass() declaring class}. For
|
||||
* static members and constructors then {@code obj} must be {@code null}.
|
||||
*
|
||||
* <p> This method returns {@code true} if the {@code accessible} flag
|
||||
* is set to {@code true}, i.e. the checks for Java language access control
|
||||
* are suppressed, or if the caller can access the member as
|
||||
* specified in <cite>The Java™ Language Specification</cite>,
|
||||
* with the variation noted in the class description. </p>
|
||||
*
|
||||
* @param obj an instance object of the declaring class of this reflected
|
||||
* object if it is an instance method or field
|
||||
*
|
||||
* @return {@code true} if the caller can access this reflected object.
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* <ul>
|
||||
* <li> if this reflected object is a static member or constructor and
|
||||
* the given {@code obj} is non-{@code null}, or </li>
|
||||
* <li> if this reflected object is an instance method or field
|
||||
* and the given {@code obj} is {@code null} or of type
|
||||
* that is not a subclass of the {@link Member#getDeclaringClass()
|
||||
* declaring class} of the member.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @since 9
|
||||
* @spec JPMS
|
||||
* @jls 6.6 Access Control
|
||||
* @see #trySetAccessible
|
||||
* @see #setAccessible(boolean)
|
||||
*/
|
||||
@CallerSensitive
|
||||
public final boolean canAccess(Object obj) {
|
||||
if (!Member.class.isInstance(this)) {
|
||||
return override;
|
||||
}
|
||||
|
||||
Class<?> declaringClass = ((Member) this).getDeclaringClass();
|
||||
int modifiers = ((Member) this).getModifiers();
|
||||
if (!Modifier.isStatic(modifiers) &&
|
||||
(this instanceof Method || this instanceof Field)) {
|
||||
if (obj == null) {
|
||||
throw new IllegalArgumentException("null object for " + this);
|
||||
}
|
||||
// if this object is an instance member, the given object
|
||||
// must be a subclass of the declaring class of this reflected object
|
||||
if (!declaringClass.isAssignableFrom(obj.getClass())) {
|
||||
throw new IllegalArgumentException("object is not an instance of "
|
||||
+ declaringClass.getName());
|
||||
}
|
||||
} else if (obj != null) {
|
||||
throw new IllegalArgumentException("non-null object for " + this);
|
||||
}
|
||||
|
||||
// access check is suppressed
|
||||
if (override) return true;
|
||||
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
Class<?> targetClass;
|
||||
if (this instanceof Constructor) {
|
||||
targetClass = declaringClass;
|
||||
} else {
|
||||
targetClass = Modifier.isStatic(modifiers) ? null : obj.getClass();
|
||||
}
|
||||
return verifyAccess(caller, declaringClass, targetClass, modifiers);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 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,targetClass},
|
||||
// or a caller (with targetClass implicitly equal to memberClass).
|
||||
// In the 2-array case, the targetClass is always different from the memberClass.
|
||||
volatile Object securityCheckCache;
|
||||
|
||||
final void checkAccess(Class<?> caller, Class<?> memberClass,
|
||||
Class<?> targetClass, int modifiers)
|
||||
throws IllegalAccessException
|
||||
{
|
||||
if (!verifyAccess(caller, memberClass, targetClass, modifiers)) {
|
||||
IllegalAccessException e = Reflection.newIllegalAccessException(
|
||||
caller, memberClass, targetClass, modifiers);
|
||||
if (printStackTraceWhenAccessFails()) {
|
||||
e.printStackTrace(System.err);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
final boolean verifyAccess(Class<?> caller, Class<?> memberClass,
|
||||
Class<?> targetClass, int modifiers)
|
||||
{
|
||||
if (caller == memberClass) { // quick check
|
||||
return true; // ACCESS IS OK
|
||||
}
|
||||
Object cache = securityCheckCache; // read volatile
|
||||
if (targetClass != null // instance member or constructor
|
||||
&& Modifier.isProtected(modifiers)
|
||||
&& targetClass != memberClass) {
|
||||
// Must match a 2-list of { caller, targetClass }.
|
||||
if (cache instanceof Class[]) {
|
||||
Class<?>[] cache2 = (Class<?>[]) cache;
|
||||
if (cache2[1] == targetClass &&
|
||||
cache2[0] == caller) {
|
||||
return true; // 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 targetClass == memberClass or static member).
|
||||
return true; // ACCESS IS OK
|
||||
}
|
||||
|
||||
// If no return, fall through to the slow path.
|
||||
return slowVerifyAccess(caller, memberClass, targetClass, modifiers);
|
||||
}
|
||||
|
||||
// Keep all this slow stuff out of line:
|
||||
private boolean slowVerifyAccess(Class<?> caller, Class<?> memberClass,
|
||||
Class<?> targetClass, int modifiers)
|
||||
{
|
||||
if (!Reflection.verifyMemberAccess(caller, memberClass, targetClass, modifiers)) {
|
||||
// access denied
|
||||
return false;
|
||||
}
|
||||
|
||||
// access okay
|
||||
logIfExportedForIllegalAccess(caller, memberClass);
|
||||
|
||||
// Success: Update the cache.
|
||||
Object cache = (targetClass != null
|
||||
&& Modifier.isProtected(modifiers)
|
||||
&& targetClass != memberClass)
|
||||
? new Class<?>[] { caller, targetClass }
|
||||
: caller;
|
||||
|
||||
// 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
|
||||
return true;
|
||||
}
|
||||
|
||||
// true to print a stack trace when access fails
|
||||
private static volatile boolean printStackWhenAccessFails;
|
||||
|
||||
// true if printStack* values are initialized
|
||||
private static volatile boolean printStackPropertiesSet;
|
||||
|
||||
/**
|
||||
* Returns true if a stack trace should be printed when access fails.
|
||||
*/
|
||||
private static boolean printStackTraceWhenAccessFails() {
|
||||
if (!printStackPropertiesSet && VM.initLevel() >= 1) {
|
||||
String s = GetPropertyAction.privilegedGetProperty(
|
||||
"sun.reflect.debugModuleAccessChecks");
|
||||
if (s != null) {
|
||||
printStackWhenAccessFails = !s.equalsIgnoreCase("false");
|
||||
}
|
||||
printStackPropertiesSet = true;
|
||||
}
|
||||
return printStackWhenAccessFails;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
|
||||
/**
|
||||
* {@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
|
||||
* @see GenericArrayType#getGenericComponentType()
|
||||
*/
|
||||
AnnotatedType getAnnotatedGenericComponentType();
|
||||
|
||||
/**
|
||||
* Returns the potentially annotated type that this type is a member of, if
|
||||
* this type represents a nested type. For example, if this type is
|
||||
* {@code @TA O<T>.I<S>}, return a representation of {@code @TA O<T>}.
|
||||
*
|
||||
* <p>Returns {@code null} for an {@code AnnotatedType} that is an instance
|
||||
* of {@code AnnotatedArrayType}.
|
||||
*
|
||||
* @return {@code null}
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
@Override
|
||||
AnnotatedType getAnnotatedOwnerType();
|
||||
}
|
|
@ -0,0 +1,466 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2017, 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 class="plain">
|
||||
* <caption>Overview of kind of presence detected by different AnnotatedElement methods</caption>
|
||||
* <thead>
|
||||
* <tr><th colspan=2 scope="col">Method</th>
|
||||
* <th colspan=4 scope="col">Kind of Presence</th>
|
||||
* <tr><th scope="col">Return Type</th>
|
||||
* <th scope="col">Signature</th>
|
||||
* <th scope="col">Directly Present</th>
|
||||
* <th scope="col">Indirectly Present</th>
|
||||
* <th scope="col">Present</th>
|
||||
* <th scope="col">Associated</th>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tr><td style="text-align:right">{@code T}</td>
|
||||
* <th scope="row" style="font-weight:normal; text-align:left">{@link #getAnnotation(Class) getAnnotation(Class<T>)}
|
||||
* <td></td><td></td><td style="text-align:center">X</td><td></td>
|
||||
* </tr>
|
||||
* <tr><td style="text-align:right">{@code Annotation[]}</td>
|
||||
* <th scope="row" style="font-weight:normal; text-align:left">{@link #getAnnotations getAnnotations()}
|
||||
* <td></td><td></td><td style="text-align:center">X</td><td></td>
|
||||
* </tr>
|
||||
* <tr><td style="text-align:right">{@code T[]}</td>
|
||||
* <th scope="row" style="font-weight:normal; text-align:left">{@link #getAnnotationsByType(Class) getAnnotationsByType(Class<T>)}
|
||||
* <td></td><td></td><td></td><td style="text-align:center">X</td>
|
||||
* </tr>
|
||||
* <tr><td style="text-align:right">{@code T}</td>
|
||||
* <th scope="row" style="font-weight:normal; text-align:left">{@link #getDeclaredAnnotation(Class) getDeclaredAnnotation(Class<T>)}
|
||||
* <td style="text-align:center">X</td><td></td><td></td><td></td>
|
||||
* </tr>
|
||||
* <tr><td style="text-align:right">{@code Annotation[]}</td>
|
||||
* <th scope="row" style="font-weight:normal; text-align:left">{@link #getDeclaredAnnotations getDeclaredAnnotations()}
|
||||
* <td style="text-align:center">X</td><td></td><td></td><td></td>
|
||||
* </tr>
|
||||
* <tr><td style="text-align:right">{@code T[]}</td>
|
||||
* <th scope="row" style="font-weight:normal; text-align:left">{@link #getDeclaredAnnotationsByType(Class) getDeclaredAnnotationsByType(Class<T>)}
|
||||
* <td style="text-align:center">X</td><td style="text-align:center">X</td><td></td><td></td>
|
||||
* </tr>
|
||||
* </tbody>
|
||||
* </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,66 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* {@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
|
||||
* @see ParameterizedType#getActualTypeArguments()
|
||||
*/
|
||||
AnnotatedType[] getAnnotatedActualTypeArguments();
|
||||
|
||||
/**
|
||||
* Returns the potentially annotated type that this type is a member of, if
|
||||
* this type represents a nested type. For example, if this type is
|
||||
* {@code @TA O<T>.I<S>}, return a representation of {@code @TA O<T>}.
|
||||
*
|
||||
* <p>Returns {@code null} if this {@code AnnotatedType} represents a
|
||||
* top-level type, or a local or anonymous class, or a primitive type, or
|
||||
* void.
|
||||
*
|
||||
* @return an {@code AnnotatedType} object representing the potentially
|
||||
* annotated type that this type is a member of, or {@code null}
|
||||
* @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 9
|
||||
*/
|
||||
@Override
|
||||
AnnotatedType getAnnotatedOwnerType();
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* 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 potentially annotated type that this type is a member of, if
|
||||
* this type represents a nested type. For example, if this type is
|
||||
* {@code @TA O<T>.I<S>}, return a representation of {@code @TA O<T>}.
|
||||
*
|
||||
* <p>Returns {@code null} if this {@code AnnotatedType} represents a
|
||||
* top-level type, or a local or anonymous class, or a primitive type, or
|
||||
* void.
|
||||
*
|
||||
* <p>Returns {@code null} if this {@code AnnotatedType} is an instance of
|
||||
* {@code AnnotatedArrayType}, {@code AnnotatedTypeVariable}, or
|
||||
* {@code AnnotatedWildcardType}.
|
||||
*
|
||||
* @implSpec
|
||||
* This default implementation returns {@code null} and performs no other
|
||||
* action.
|
||||
*
|
||||
* @return an {@code AnnotatedType} object representing the potentially
|
||||
* annotated type that this type is a member of, or {@code null}
|
||||
* @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 9
|
||||
*/
|
||||
default AnnotatedType getAnnotatedOwnerType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the underlying type that this annotated type represents.
|
||||
*
|
||||
* @return the type this annotated type represents
|
||||
*/
|
||||
public Type getType();
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* {@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.
|
||||
* If no bound is explicitly declared, the bound is unannotated
|
||||
* {@code Object}.
|
||||
*
|
||||
* @return the potentially annotated bounds of this type variable
|
||||
* @see TypeVariable#getBounds()
|
||||
*/
|
||||
AnnotatedType[] getAnnotatedBounds();
|
||||
|
||||
/**
|
||||
* Returns the potentially annotated type that this type is a member of, if
|
||||
* this type represents a nested type. For example, if this type is
|
||||
* {@code @TA O<T>.I<S>}, return a representation of {@code @TA O<T>}.
|
||||
*
|
||||
* <p>Returns {@code null} for an {@code AnnotatedType} that is an instance
|
||||
* of {@code AnnotatedTypeVariable}.
|
||||
*
|
||||
* @return {@code null}
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
@Override
|
||||
AnnotatedType getAnnotatedOwnerType();
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* {@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.
|
||||
* If no lower bound is explicitly declared, the lower bound is the
|
||||
* type of null. In this case, a zero length array is returned.
|
||||
*
|
||||
* @return the potentially annotated lower bounds of this wildcard type or
|
||||
* an empty array if no lower bound is explicitly declared.
|
||||
* @see WildcardType#getLowerBounds()
|
||||
*/
|
||||
AnnotatedType[] getAnnotatedLowerBounds();
|
||||
|
||||
/**
|
||||
* Returns the potentially annotated upper bounds of this wildcard type.
|
||||
* If no upper bound is explicitly declared, the upper bound is
|
||||
* unannotated {@code Object}
|
||||
*
|
||||
* @return the potentially annotated upper bounds of this wildcard type
|
||||
* @see WildcardType#getUpperBounds()
|
||||
*/
|
||||
AnnotatedType[] getAnnotatedUpperBounds();
|
||||
|
||||
/**
|
||||
* Returns the potentially annotated type that this type is a member of, if
|
||||
* this type represents a nested type. For example, if this type is
|
||||
* {@code @TA O<T>.I<S>}, return a representation of {@code @TA O<T>}.
|
||||
*
|
||||
* <p>Returns {@code null} for an {@code AnnotatedType} that is an instance
|
||||
* of {@code AnnotatedWildcardType}.
|
||||
*
|
||||
* @return {@code null}
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
@Override
|
||||
AnnotatedType getAnnotatedOwnerType();
|
||||
}
|
493
src/java.base/share/classes/java/lang/reflect/Array.java
Normal file
493
src/java.base/share/classes/java/lang/reflect/Array.java
Normal file
|
@ -0,0 +1,493 @@
|
|||
/*
|
||||
* 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 jdk.internal.HotSpotIntrinsicCandidate;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @since 1.1
|
||||
*/
|
||||
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
|
||||
*/
|
||||
@HotSpotIntrinsicCandidate
|
||||
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
|
||||
*/
|
||||
|
||||
@HotSpotIntrinsicCandidate
|
||||
private static native Object newArray(Class<?> componentType, int length)
|
||||
throws NegativeArraySizeException;
|
||||
|
||||
private static native Object multiNewArray(Class<?> componentType,
|
||||
int[] dimensions)
|
||||
throws IllegalArgumentException, NegativeArraySizeException;
|
||||
|
||||
|
||||
}
|
654
src/java.base/share/classes/java/lang/reflect/Constructor.java
Normal file
654
src/java.base/share/classes/java/lang/reflect/Constructor.java
Normal file
|
@ -0,0 +1,654 @@
|
|||
/*
|
||||
* Copyright (c) 1996, 2017, 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 jdk.internal.misc.SharedSecrets;
|
||||
import jdk.internal.reflect.CallerSensitive;
|
||||
import jdk.internal.reflect.ConstructorAccessor;
|
||||
import jdk.internal.reflect.Reflection;
|
||||
import jdk.internal.vm.annotation.ForceInline;
|
||||
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;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
/**
|
||||
* {@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
|
||||
* @since 1.1
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p> A {@code SecurityException} is also thrown if this object is a
|
||||
* {@code Constructor} object for the class {@code Class} and {@code flag}
|
||||
* is true. </p>
|
||||
*
|
||||
* @param flag {@inheritDoc}
|
||||
*
|
||||
* @throws InaccessibleObjectException {@inheritDoc}
|
||||
* @throws SecurityException if the request is denied by the security manager
|
||||
* or this is a constructor for {@code java.lang.Class}
|
||||
*
|
||||
* @spec JPMS
|
||||
*/
|
||||
@Override
|
||||
@CallerSensitive
|
||||
public void setAccessible(boolean flag) {
|
||||
AccessibleObject.checkPermission();
|
||||
if (flag) {
|
||||
checkCanSetAccessible(Reflection.getCallerClass());
|
||||
}
|
||||
setAccessible0(flag);
|
||||
}
|
||||
|
||||
@Override
|
||||
void checkCanSetAccessible(Class<?> caller) {
|
||||
checkCanSetAccessible(caller, clazz);
|
||||
if (clazz == Class.class) {
|
||||
// can we change this to InaccessibleObjectException?
|
||||
throw new SecurityException("Cannot make a java.lang.Class"
|
||||
+ " constructor accessible");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean hasGenericInformation() {
|
||||
return (getSignature() != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
byte[] getAnnotationBytes() {
|
||||
return annotations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@code Class} object representing the class that
|
||||
* declares the constructor represented by this object.
|
||||
*/
|
||||
@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];
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
Class<?>[] getSharedParameterTypes() {
|
||||
return parameterTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@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>{@code
|
||||
* public java.util.Hashtable(int,float)
|
||||
* }</pre>
|
||||
*
|
||||
* <p>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}
|
||||
* @jls 8.8.3 Constructor Modifiers
|
||||
* @jls 8.9.2 Enum Body Declarations
|
||||
*/
|
||||
public String toString() {
|
||||
return sharedToString(Modifier.constructorModifiers(),
|
||||
false,
|
||||
parameterTypes,
|
||||
exceptionTypes);
|
||||
}
|
||||
|
||||
@Override
|
||||
void specificToStringHeader(StringBuilder sb) {
|
||||
sb.append(getDeclaringClass().getTypeName());
|
||||
}
|
||||
|
||||
@Override
|
||||
String toShortString() {
|
||||
StringBuilder sb = new StringBuilder("constructor ");
|
||||
sb.append(getDeclaringClass().getTypeName());
|
||||
sb.append('(');
|
||||
StringJoiner sj = new StringJoiner(",");
|
||||
for (Class<?> parameterType : getParameterTypes()) {
|
||||
sj.add(parameterType.getTypeName());
|
||||
}
|
||||
sb.append(sj);
|
||||
sb.append(')');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* "<code><i>Type</i>[]</code>", it is denoted as
|
||||
* "<code><i>Type</i>...</code>".
|
||||
*
|
||||
* A space is used to separate access modifiers from one another
|
||||
* and from the type parameters or class name. 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 generic 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
|
||||
* @jls 8.9.2 Enum Body Declarations
|
||||
*/
|
||||
@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
|
||||
@ForceInline // to ensure Reflection.getCallerClass optimization
|
||||
public T newInstance(Object ... initargs)
|
||||
throws InstantiationException, IllegalAccessException,
|
||||
IllegalArgumentException, InvocationTargetException
|
||||
{
|
||||
if (!override) {
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
checkAccess(caller, clazz, clazz, 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
|
||||
boolean handleParameterNumberMismatch(int resultLength, int numParameters) {
|
||||
Class<?> declaringClass = getDeclaringClass();
|
||||
if (declaringClass.isEnum() ||
|
||||
declaringClass.isAnonymousClass() ||
|
||||
declaringClass.isLocalClass() )
|
||||
return false; // Can't do reliable parameter counting
|
||||
else {
|
||||
if (declaringClass.isMemberClass() &&
|
||||
((declaringClass.getModifiers() & Modifier.STATIC) == 0) &&
|
||||
resultLength + 1 == numParameters) {
|
||||
return true;
|
||||
} else {
|
||||
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() {
|
||||
Class<?> thisDeclClass = getDeclaringClass();
|
||||
Class<?> enclosingClass = thisDeclClass.getEnclosingClass();
|
||||
|
||||
if (enclosingClass == null) {
|
||||
// A Constructor for a top-level class
|
||||
return null;
|
||||
}
|
||||
|
||||
Class<?> outerDeclaringClass = thisDeclClass.getDeclaringClass();
|
||||
if (outerDeclaringClass == null) {
|
||||
// A constructor for a local or anonymous class
|
||||
return null;
|
||||
}
|
||||
|
||||
// Either static nested or inner class
|
||||
if (Modifier.isStatic(thisDeclClass.getModifiers())) {
|
||||
// static nested
|
||||
return null;
|
||||
}
|
||||
|
||||
// A Constructor for an inner class
|
||||
return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes0(),
|
||||
SharedSecrets.getJavaLangAccess().
|
||||
getConstantPool(thisDeclClass),
|
||||
this,
|
||||
thisDeclClass,
|
||||
enclosingClass,
|
||||
TypeAnnotation.TypeAnnotationTarget.METHOD_RECEIVER);
|
||||
}
|
||||
}
|
734
src/java.base/share/classes/java/lang/reflect/Executable.java
Normal file
734
src/java.base/share/classes/java/lang/reflect/Executable.java
Normal file
|
@ -0,0 +1,734 @@
|
|||
/*
|
||||
* Copyright (c) 2012, 2017, 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 java.util.StringJoiner;
|
||||
|
||||
import jdk.internal.misc.SharedSecrets;
|
||||
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,
|
||||
SharedSecrets.getJavaLangAccess().
|
||||
getConstantPool(getDeclaringClass()),
|
||||
getDeclaringClass());
|
||||
}
|
||||
|
||||
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('(');
|
||||
StringJoiner sj = new StringJoiner(",");
|
||||
for (Class<?> parameterType : parameterTypes) {
|
||||
sj.add(parameterType.getTypeName());
|
||||
}
|
||||
sb.append(sj.toString());
|
||||
sb.append(')');
|
||||
|
||||
if (exceptionTypes.length > 0) {
|
||||
StringJoiner joiner = new StringJoiner(",", " throws ", "");
|
||||
for (Class<?> exceptionType : exceptionTypes) {
|
||||
joiner.add(exceptionType.getTypeName());
|
||||
}
|
||||
sb.append(joiner.toString());
|
||||
}
|
||||
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) {
|
||||
StringJoiner sj = new StringJoiner(",", "<", "> ");
|
||||
for(TypeVariable<?> typeparm: typeparms) {
|
||||
sj.add(typeparm.getTypeName());
|
||||
}
|
||||
sb.append(sj.toString());
|
||||
}
|
||||
|
||||
specificToGenericStringHeader(sb);
|
||||
|
||||
sb.append('(');
|
||||
StringJoiner sj = new StringJoiner(",");
|
||||
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("\\[\\]$", "...");
|
||||
sj.add(param);
|
||||
}
|
||||
sb.append(sj.toString());
|
||||
sb.append(')');
|
||||
|
||||
Type[] exceptionTypes = getGenericExceptionTypes();
|
||||
if (exceptionTypes.length > 0) {
|
||||
StringJoiner joiner = new StringJoiner(",", " throws ", "");
|
||||
for (Type exceptionType : exceptionTypes) {
|
||||
joiner.add(exceptionType.getTypeName());
|
||||
}
|
||||
sb.append(joiner.toString());
|
||||
}
|
||||
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 shared array of parameter types - must never give it out
|
||||
// to the untrusted code...
|
||||
abstract Class<?>[] getSharedParameterTypes();
|
||||
|
||||
/**
|
||||
* 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)) {
|
||||
Annotation[][] tmp = new Annotation[result.length+1][];
|
||||
// Shift annotations down one to account for an implicit leading parameter
|
||||
System.arraycopy(result, 0, tmp, 1, result.length);
|
||||
tmp[0] = new Annotation[0];
|
||||
result = tmp;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
abstract boolean 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(),
|
||||
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(),
|
||||
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 {@code Executable} object.
|
||||
*
|
||||
* The receiver type of a method/constructor is available only if the
|
||||
* method/constructor has a receiver parameter (JLS 8.4.1). If this {@code
|
||||
* Executable} object <em>represents an instance method or represents a
|
||||
* constructor of an inner member class</em>, and the
|
||||
* method/constructor <em>either</em> has no 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 or
|
||||
* represents a constructor of a top level, static member, local, or
|
||||
* anonymous class, then the return value is null.
|
||||
*
|
||||
* @return an object representing the receiver type of the method or
|
||||
* constructor represented by this {@code Executable} or {@code null} if
|
||||
* this {@code Executable} can not have a receiver parameter
|
||||
*/
|
||||
public AnnotatedType getAnnotatedReceiverType() {
|
||||
if (Modifier.isStatic(this.getModifiers()))
|
||||
return null;
|
||||
return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes0(),
|
||||
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(),
|
||||
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(),
|
||||
SharedSecrets.getJavaLangAccess().
|
||||
getConstantPool(getDeclaringClass()),
|
||||
this,
|
||||
getDeclaringClass(),
|
||||
getGenericExceptionTypes(),
|
||||
TypeAnnotation.TypeAnnotationTarget.THROWS);
|
||||
}
|
||||
|
||||
}
|
1202
src/java.base/share/classes/java/lang/reflect/Field.java
Normal file
1202
src/java.base/share/classes/java/lang/reflect/Field.java
Normal file
File diff suppressed because it is too large
Load diff
|
@ -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();
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 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;
|
||||
|
||||
/**
|
||||
* Thrown when Java language access checks cannot be suppressed.
|
||||
*
|
||||
* @see AccessibleObject#setAccessible(boolean)
|
||||
* @since 9
|
||||
* @spec JPMS
|
||||
*/
|
||||
|
||||
public class InaccessibleObjectException extends RuntimeException {
|
||||
private static final long serialVersionUID = 4158786093378140901L;
|
||||
|
||||
/**
|
||||
* Constructs an {@code InaccessibleObjectException} with no detail message.
|
||||
*/
|
||||
public InaccessibleObjectException() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an {@code InaccessibleObjectException} with the given detail
|
||||
* message.
|
||||
*
|
||||
* @param msg
|
||||
* The detail message
|
||||
*/
|
||||
public InaccessibleObjectException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* 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
|
||||
* @since 1.1
|
||||
*/
|
||||
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,56 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2017, 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;
|
||||
|
||||
/**
|
||||
* Constructs a {@code MalformedParameterizedTypeException} with
|
||||
* no detail message.
|
||||
*/
|
||||
public MalformedParameterizedTypeException() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a {@code MalformedParameterizedTypeException} with
|
||||
* the given detail message.
|
||||
* @param message the detail message; may be {@code null}
|
||||
*/
|
||||
public MalformedParameterizedTypeException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
93
src/java.base/share/classes/java/lang/reflect/Member.java
Normal file
93
src/java.base/share/classes/java/lang/reflect/Member.java
Normal file
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* 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
|
||||
* @since 1.1
|
||||
*/
|
||||
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();
|
||||
}
|
726
src/java.base/share/classes/java/lang/reflect/Method.java
Normal file
726
src/java.base/share/classes/java/lang/reflect/Method.java
Normal file
|
@ -0,0 +1,726 @@
|
|||
/*
|
||||
* Copyright (c) 1996, 2017, 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 jdk.internal.HotSpotIntrinsicCandidate;
|
||||
import jdk.internal.misc.SharedSecrets;
|
||||
import jdk.internal.reflect.CallerSensitive;
|
||||
import jdk.internal.reflect.MethodAccessor;
|
||||
import jdk.internal.reflect.Reflection;
|
||||
import jdk.internal.vm.annotation.ForceInline;
|
||||
import sun.reflect.annotation.ExceptionProxy;
|
||||
import sun.reflect.annotation.TypeNotPresentExceptionProxy;
|
||||
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;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @since 1.1
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a copy of a leaf method.
|
||||
*/
|
||||
Method leafCopy() {
|
||||
if (this.root == null)
|
||||
throw new IllegalArgumentException("Can only leafCopy a non-root Method");
|
||||
|
||||
Method res = new Method(clazz, name, parameterTypes, returnType,
|
||||
exceptionTypes, modifiers, slot, signature,
|
||||
annotations, parameterAnnotations, annotationDefault);
|
||||
res.root = root;
|
||||
res.methodAccessor = methodAccessor;
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws InaccessibleObjectException {@inheritDoc}
|
||||
* @throws SecurityException {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
@CallerSensitive
|
||||
public void setAccessible(boolean flag) {
|
||||
AccessibleObject.checkPermission();
|
||||
if (flag) checkCanSetAccessible(Reflection.getCallerClass());
|
||||
setAccessible0(flag);
|
||||
}
|
||||
|
||||
@Override
|
||||
void checkCanSetAccessible(Class<?> caller) {
|
||||
checkCanSetAccessible(caller, clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by Excecutable for annotation sharing.
|
||||
*/
|
||||
@Override
|
||||
Executable getRoot() {
|
||||
return root;
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean hasGenericInformation() {
|
||||
return (getGenericSignature() != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
byte[] getAnnotationBytes() {
|
||||
return annotations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@code Class} object representing the class or interface
|
||||
* that declares the method represented by this object.
|
||||
*/
|
||||
@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();}
|
||||
}
|
||||
|
||||
@Override
|
||||
Class<?>[] getSharedParameterTypes() {
|
||||
return parameterTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@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 "{@code 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
|
||||
* @jls 9.4 Method Declarations
|
||||
* @jls 9.6.1 Annotation Type Elements
|
||||
*/
|
||||
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());
|
||||
}
|
||||
|
||||
@Override
|
||||
String toShortString() {
|
||||
StringBuilder sb = new StringBuilder("method ");
|
||||
sb.append(getDeclaringClass().getTypeName()).append('.');
|
||||
sb.append(getName());
|
||||
sb.append('(');
|
||||
StringJoiner sj = new StringJoiner(",");
|
||||
for (Class<?> parameterType : getParameterTypes()) {
|
||||
sj.add(parameterType.getTypeName());
|
||||
}
|
||||
sb.append(sj);
|
||||
sb.append(')');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* "<code><i>Type</i>[]</code>", it is denoted as
|
||||
* "<code><i>Type</i>...</code>".
|
||||
*
|
||||
* 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
|
||||
* "{@code 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
|
||||
* @jls 9.4 Method Declarations
|
||||
* @jls 9.6.1 Annotation Type Elements
|
||||
*/
|
||||
@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
|
||||
@ForceInline // to ensure Reflection.getCallerClass optimization
|
||||
@HotSpotIntrinsicCandidate
|
||||
public Object invoke(Object obj, Object... args)
|
||||
throws IllegalAccessException, IllegalArgumentException,
|
||||
InvocationTargetException
|
||||
{
|
||||
if (!override) {
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
checkAccess(caller, clazz,
|
||||
Modifier.isStatic(modifiers) ? null : obj.getClass(),
|
||||
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),
|
||||
SharedSecrets.getJavaLangAccess().
|
||||
getConstantPool(getDeclaringClass()),
|
||||
getDeclaringClass());
|
||||
if (result instanceof ExceptionProxy) {
|
||||
if (result instanceof TypeNotPresentExceptionProxy) {
|
||||
TypeNotPresentExceptionProxy proxy = (TypeNotPresentExceptionProxy)result;
|
||||
throw new TypeNotPresentException(proxy.typeName(), proxy.getCause());
|
||||
}
|
||||
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
|
||||
boolean handleParameterNumberMismatch(int resultLength, int numParameters) {
|
||||
throw new AnnotationFormatError("Parameter annotations don't match number of parameters");
|
||||
}
|
||||
}
|
494
src/java.base/share/classes/java/lang/reflect/Modifier.java
Normal file
494
src/java.base/share/classes/java/lang/reflect/Modifier.java
Normal file
|
@ -0,0 +1,494 @@
|
|||
/*
|
||||
* 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 java.util.StringJoiner;
|
||||
import jdk.internal.reflect.LangReflectAccess;
|
||||
import jdk.internal.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
|
||||
* @since 1.1
|
||||
*/
|
||||
public class Modifier {
|
||||
|
||||
/*
|
||||
* Bootstrapping protocol between java.lang and java.lang.reflect
|
||||
* packages
|
||||
*/
|
||||
static {
|
||||
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) {
|
||||
StringJoiner sj = new StringJoiner(" ");
|
||||
|
||||
if ((mod & PUBLIC) != 0) sj.add("public");
|
||||
if ((mod & PROTECTED) != 0) sj.add("protected");
|
||||
if ((mod & PRIVATE) != 0) sj.add("private");
|
||||
|
||||
/* Canonical order */
|
||||
if ((mod & ABSTRACT) != 0) sj.add("abstract");
|
||||
if ((mod & STATIC) != 0) sj.add("static");
|
||||
if ((mod & FINAL) != 0) sj.add("final");
|
||||
if ((mod & TRANSIENT) != 0) sj.add("transient");
|
||||
if ((mod & VOLATILE) != 0) sj.add("volatile");
|
||||
if ((mod & SYNCHRONIZED) != 0) sj.add("synchronized");
|
||||
if ((mod & NATIVE) != 0) sj.add("native");
|
||||
if ((mod & STRICT) != 0) sj.add("strictfp");
|
||||
if ((mod & INTERFACE) != 0) sj.add("interface");
|
||||
|
||||
return sj.toString();
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
347
src/java.base/share/classes/java/lang/reflect/Parameter.java
Normal file
347
src/java.base/share/classes/java/lang/reflect/Parameter.java
Normal file
|
@ -0,0 +1,347 @@
|
|||
/*
|
||||
* 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 parameter 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;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* 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<>();
|
||||
for (Annotation a : getDeclaredAnnotations())
|
||||
declaredAnnotations.put(a.annotationType(), a);
|
||||
}
|
||||
return declaredAnnotations;
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
1119
src/java.base/share/classes/java/lang/reflect/Proxy.java
Normal file
1119
src/java.base/share/classes/java/lang/reflect/Proxy.java
Normal file
File diff suppressed because it is too large
Load diff
2031
src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java
Normal file
2031
src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java
Normal file
File diff suppressed because it is too large
Load diff
157
src/java.base/share/classes/java/lang/reflect/ReflectAccess.java
Normal file
157
src/java.base/share/classes/java/lang/reflect/ReflectAccess.java
Normal file
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
* 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 jdk.internal.reflect.MethodAccessor;
|
||||
import jdk.internal.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 jdk.internal.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();
|
||||
}
|
||||
|
||||
public Class<?>[] getExecutableSharedParameterTypes(Executable ex) {
|
||||
return ex.getSharedParameterTypes();
|
||||
}
|
||||
|
||||
//
|
||||
// Copying routines, needed to quickly fabricate new Field,
|
||||
// Method, and Constructor objects from templates
|
||||
//
|
||||
public Method copyMethod(Method arg) {
|
||||
return arg.copy();
|
||||
}
|
||||
public Method leafCopyMethod(Method arg) {
|
||||
return arg.leafCopy();
|
||||
}
|
||||
|
||||
public Field copyField(Field arg) {
|
||||
return arg.copy();
|
||||
}
|
||||
|
||||
public <T> Constructor<T> copyConstructor(Constructor<T> arg) {
|
||||
return arg.copy();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* Copyright (c) 1997, 2017, 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 class="striped">
|
||||
* <caption style="display:none">Table shows permission target name, what the permission allows, and associated risks</caption>
|
||||
* <thead>
|
||||
* <tr>
|
||||
* <th scope="col">Permission Target Name</th>
|
||||
* <th scope="col">What the Permission Allows</th>
|
||||
* <th scope="col">Risks of Allowing this Permission</th>
|
||||
* </tr>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
*
|
||||
* <tr>
|
||||
* <th scope="row">suppressAccessChecks</th>
|
||||
* <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>
|
||||
* <th scope="row">newProxyInPackage.{package name}</th>
|
||||
* <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>
|
||||
*
|
||||
* </tbody>
|
||||
* </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
src/java.base/share/classes/java/lang/reflect/Type.java
Normal file
48
src/java.base/share/classes/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
src/java.base/share/classes/java/lang/reflect/TypeVariable.java
Normal file
102
src/java.base/share/classes/java/lang/reflect/TypeVariable.java
Normal file
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 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;
|
||||
|
||||
/**
|
||||
* 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. 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. Note that
|
||||
* if no upper bound is explicitly declared, the upper bound is unannotated
|
||||
* {@code Object}.
|
||||
*
|
||||
* @return an array of objects representing the upper bound(s) of the type variable
|
||||
* @since 1.8
|
||||
*/
|
||||
AnnotatedType[] getAnnotatedBounds();
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 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;
|
||||
|
||||
/**
|
||||
* 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. 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. 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.
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 2017, 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 encapsulation and 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 1.1
|
||||
* @revised 9
|
||||
* @spec JPMS
|
||||
*/
|
||||
package java.lang.reflect;
|
Loading…
Add table
Add a link
Reference in a new issue