2014-08-13 10:39:27 +01:00
|
|
|
/*
|
2015-09-24 06:06:07 -04:00
|
|
|
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
|
2014-08-13 10:39:27 +01:00
|
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
|
|
*
|
|
|
|
* This code is free software; you can redistribute it and/or modify it
|
|
|
|
* under the terms of the GNU General Public License version 2 only, as
|
|
|
|
* published by the Free Software Foundation. Oracle designates this
|
|
|
|
* particular file as subject to the "Classpath" exception as provided
|
|
|
|
* by Oracle in the LICENSE file that accompanied this code.
|
|
|
|
*
|
|
|
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
|
|
* version 2 for more details (a copy is included in the LICENSE file that
|
|
|
|
* accompanied this code).
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License version
|
|
|
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
*
|
|
|
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
|
|
* or visit www.oracle.com if you need additional information or have any
|
|
|
|
* questions.
|
|
|
|
*/
|
|
|
|
|
|
|
|
package java.lang.reflect;
|
|
|
|
|
|
|
|
import sun.reflect.CallerSensitive;
|
|
|
|
import sun.reflect.ConstructorAccessor;
|
|
|
|
import sun.reflect.Reflection;
|
2015-09-24 06:06:07 -04:00
|
|
|
import sun.reflect.annotation.TypeAnnotation;
|
|
|
|
import sun.reflect.annotation.TypeAnnotationParser;
|
2014-08-13 10:39:27 +01:00
|
|
|
import sun.reflect.generics.repository.ConstructorRepository;
|
|
|
|
import sun.reflect.generics.factory.CoreReflectionFactory;
|
|
|
|
import sun.reflect.generics.factory.GenericsFactory;
|
|
|
|
import sun.reflect.generics.scope.ConstructorScope;
|
|
|
|
import java.lang.annotation.Annotation;
|
|
|
|
import java.lang.annotation.AnnotationFormatError;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* {@code Constructor} provides information about, and access to, a single
|
|
|
|
* constructor for a class.
|
|
|
|
*
|
|
|
|
* <p>{@code Constructor} permits widening conversions to occur when matching the
|
|
|
|
* actual parameters to newInstance() with the underlying
|
|
|
|
* constructor's formal parameters, but throws an
|
|
|
|
* {@code IllegalArgumentException} if a narrowing conversion would occur.
|
|
|
|
*
|
|
|
|
* @param <T> the class in which the constructor is declared
|
|
|
|
*
|
|
|
|
* @see Member
|
|
|
|
* @see java.lang.Class
|
|
|
|
* @see java.lang.Class#getConstructors()
|
|
|
|
* @see java.lang.Class#getConstructor(Class[])
|
|
|
|
* @see java.lang.Class#getDeclaredConstructors()
|
|
|
|
*
|
|
|
|
* @author Kenneth Russell
|
|
|
|
* @author Nakul Saraiya
|
|
|
|
*/
|
2015-09-24 06:06:07 -04:00
|
|
|
public final class Constructor<T> extends Executable {
|
2014-08-13 10:39:27 +01:00
|
|
|
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;
|
|
|
|
|
|
|
|
// Generics infrastructure
|
|
|
|
// Accessor for factory
|
|
|
|
private GenericsFactory getFactory() {
|
|
|
|
// create scope and factory
|
|
|
|
return CoreReflectionFactory.make(this, ConstructorScope.make(this));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Accessor for generic info repository
|
2015-09-24 06:06:07 -04:00
|
|
|
@Override
|
|
|
|
ConstructorRepository getGenericInfo() {
|
2014-08-13 10:39:27 +01:00
|
|
|
// 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.)
|
2015-09-24 06:06:07 -04:00
|
|
|
//
|
|
|
|
// If this branching structure would ever contain cycles, deadlocks can
|
|
|
|
// occur in annotation code.
|
2014-08-13 10:39:27 +01:00
|
|
|
private Constructor<T> root;
|
|
|
|
|
2015-09-24 06:06:07 -04:00
|
|
|
/**
|
|
|
|
* Used by Excecutable for annotation sharing.
|
|
|
|
*/
|
|
|
|
@Override
|
|
|
|
Executable getRoot() {
|
|
|
|
return root;
|
|
|
|
}
|
|
|
|
|
2014-08-13 10:39:27 +01:00
|
|
|
/**
|
|
|
|
* 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[] unused1,
|
2015-09-24 06:06:07 -04:00
|
|
|
byte[] unused2) {
|
2014-08-13 10:39:27 +01:00
|
|
|
this.clazz = declaringClass;
|
|
|
|
this.parameterTypes = parameterTypes;
|
|
|
|
this.exceptionTypes = checkedExceptions;
|
|
|
|
this.modifiers = modifiers;
|
|
|
|
this.slot = slot;
|
|
|
|
this.signature = signature;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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.)
|
2015-09-24 06:06:07 -04:00
|
|
|
if (this.root != null)
|
|
|
|
throw new IllegalArgumentException("Can not copy a non-root Constructor");
|
|
|
|
|
2014-08-13 10:39:27 +01:00
|
|
|
Constructor<T> res = new Constructor<>(clazz,
|
2015-09-24 06:06:07 -04:00
|
|
|
parameterTypes,
|
|
|
|
exceptionTypes, modifiers, slot,
|
|
|
|
signature,
|
|
|
|
null,
|
|
|
|
null);
|
2014-08-13 10:39:27 +01:00
|
|
|
res.root = this;
|
|
|
|
// Might as well eagerly propagate this if already present
|
|
|
|
res.constructorAccessor = constructorAccessor;
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2015-09-24 06:06:07 -04:00
|
|
|
@Override
|
|
|
|
boolean hasGenericInformation() {
|
|
|
|
return (getSignature() != null);
|
|
|
|
}
|
|
|
|
|
2014-08-13 10:39:27 +01:00
|
|
|
/**
|
2015-09-24 06:06:07 -04:00
|
|
|
* {@inheritDoc}
|
2014-08-13 10:39:27 +01:00
|
|
|
*/
|
2015-09-24 06:06:07 -04:00
|
|
|
@Override
|
2014-08-13 10:39:27 +01:00
|
|
|
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.
|
|
|
|
*/
|
2015-09-24 06:06:07 -04:00
|
|
|
@Override
|
2014-08-13 10:39:27 +01:00
|
|
|
public String getName() {
|
|
|
|
return getDeclaringClass().getName();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2015-09-24 06:06:07 -04:00
|
|
|
* {@inheritDoc}
|
2014-08-13 10:39:27 +01:00
|
|
|
*/
|
2015-09-24 06:06:07 -04:00
|
|
|
@Override
|
2014-08-13 10:39:27 +01:00
|
|
|
public int getModifiers() {
|
|
|
|
return modifiers;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2015-09-24 06:06:07 -04:00
|
|
|
* {@inheritDoc}
|
|
|
|
* @throws GenericSignatureFormatError {@inheritDoc}
|
2014-08-13 10:39:27 +01:00
|
|
|
* @since 1.5
|
|
|
|
*/
|
2015-09-24 06:06:07 -04:00
|
|
|
@Override
|
|
|
|
@SuppressWarnings({"rawtypes", "unchecked"})
|
2014-08-13 10:39:27 +01:00
|
|
|
public TypeVariable<Constructor<T>>[] getTypeParameters() {
|
|
|
|
if (getSignature() != null) {
|
|
|
|
return (TypeVariable<Constructor<T>>[])getGenericInfo().getTypeParameters();
|
|
|
|
} else
|
|
|
|
return (TypeVariable<Constructor<T>>[])new TypeVariable[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2015-09-24 06:06:07 -04:00
|
|
|
* {@inheritDoc}
|
2014-08-13 10:39:27 +01:00
|
|
|
*/
|
2015-09-24 06:06:07 -04:00
|
|
|
@Override
|
2014-08-13 10:39:27 +01:00
|
|
|
public Class<?>[] getParameterTypes() {
|
2015-09-24 06:06:07 -04:00
|
|
|
return parameterTypes.clone();
|
2014-08-13 10:39:27 +01:00
|
|
|
}
|
|
|
|
|
2015-09-24 06:06:07 -04:00
|
|
|
/**
|
|
|
|
* {@inheritDoc}
|
|
|
|
*/
|
|
|
|
public int getParameterCount() { return parameterTypes.length; }
|
2014-08-13 10:39:27 +01:00
|
|
|
|
|
|
|
/**
|
2015-09-24 06:06:07 -04:00
|
|
|
* {@inheritDoc}
|
|
|
|
* @throws GenericSignatureFormatError {@inheritDoc}
|
|
|
|
* @throws TypeNotPresentException {@inheritDoc}
|
|
|
|
* @throws MalformedParameterizedTypeException {@inheritDoc}
|
2014-08-13 10:39:27 +01:00
|
|
|
* @since 1.5
|
|
|
|
*/
|
2015-09-24 06:06:07 -04:00
|
|
|
@Override
|
2014-08-13 10:39:27 +01:00
|
|
|
public Type[] getGenericParameterTypes() {
|
2015-09-24 06:06:07 -04:00
|
|
|
return super.getGenericParameterTypes();
|
2014-08-13 10:39:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2015-09-24 06:06:07 -04:00
|
|
|
* {@inheritDoc}
|
2014-08-13 10:39:27 +01:00
|
|
|
*/
|
2015-09-24 06:06:07 -04:00
|
|
|
@Override
|
2014-08-13 10:39:27 +01:00
|
|
|
public Class<?>[] getExceptionTypes() {
|
2015-09-24 06:06:07 -04:00
|
|
|
return exceptionTypes.clone();
|
2014-08-13 10:39:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2015-09-24 06:06:07 -04:00
|
|
|
* {@inheritDoc}
|
|
|
|
* @throws GenericSignatureFormatError {@inheritDoc}
|
|
|
|
* @throws TypeNotPresentException {@inheritDoc}
|
|
|
|
* @throws MalformedParameterizedTypeException {@inheritDoc}
|
2014-08-13 10:39:27 +01:00
|
|
|
* @since 1.5
|
|
|
|
*/
|
2015-09-24 06:06:07 -04:00
|
|
|
@Override
|
|
|
|
public Type[] getGenericExceptionTypes() {
|
|
|
|
return super.getGenericExceptionTypes();
|
|
|
|
}
|
2014-08-13 10:39:27 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* 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()) {
|
2015-09-24 06:06:07 -04:00
|
|
|
return equalParamTypes(parameterTypes, other.parameterTypes);
|
2014-08-13 10:39:27 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns a hashcode for this {@code Constructor}. The hashcode is
|
|
|
|
* the same as the hashcode for the underlying constructor's
|
|
|
|
* declaring class name.
|
|
|
|
*/
|
|
|
|
public int hashCode() {
|
|
|
|
return getDeclaringClass().getName().hashCode();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns a string describing this {@code Constructor}. The string is
|
|
|
|
* formatted as the constructor access modifiers, if any,
|
|
|
|
* followed by the fully-qualified name of the declaring class,
|
|
|
|
* followed by a parenthesized, comma-separated list of the
|
|
|
|
* constructor's formal parameter types. For example:
|
|
|
|
* <pre>
|
|
|
|
* public java.util.Hashtable(int,float)
|
|
|
|
* </pre>
|
|
|
|
*
|
|
|
|
* <p>The only possible modifiers for constructors are the access
|
|
|
|
* modifiers {@code public}, {@code protected} or
|
|
|
|
* {@code private}. Only one of these may appear, or none if the
|
|
|
|
* constructor has default (package) access.
|
2015-09-24 06:06:07 -04:00
|
|
|
*
|
|
|
|
* @return a string describing this {@code Constructor}
|
|
|
|
* @jls 8.8.3. Constructor Modifiers
|
2014-08-13 10:39:27 +01:00
|
|
|
*/
|
|
|
|
public String toString() {
|
2015-09-24 06:06:07 -04:00
|
|
|
return sharedToString(Modifier.constructorModifiers(),
|
|
|
|
false,
|
|
|
|
parameterTypes,
|
|
|
|
exceptionTypes);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
void specificToStringHeader(StringBuilder sb) {
|
|
|
|
sb.append(getDeclaringClass().getTypeName());
|
2014-08-13 10:39:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns a string describing this {@code Constructor},
|
|
|
|
* including type parameters. The string is formatted as the
|
|
|
|
* constructor access modifiers, if any, followed by an
|
|
|
|
* angle-bracketed comma separated list of the constructor's type
|
|
|
|
* parameters, if any, followed by the fully-qualified name of the
|
|
|
|
* declaring class, followed by a parenthesized, comma-separated
|
|
|
|
* list of the constructor's generic formal parameter types.
|
|
|
|
*
|
|
|
|
* If this constructor was declared to take a variable number of
|
|
|
|
* arguments, instead of denoting the last parameter as
|
|
|
|
* "<tt><i>Type</i>[]</tt>", it is denoted as
|
|
|
|
* "<tt><i>Type</i>...</tt>".
|
|
|
|
*
|
|
|
|
* A space is used to separate access modifiers from one another
|
|
|
|
* and from the type parameters or return type. If there are no
|
|
|
|
* type parameters, the type parameter list is elided; if the type
|
|
|
|
* parameter list is present, a space separates the list from the
|
|
|
|
* class name. If the constructor is declared to throw
|
|
|
|
* exceptions, the parameter list is followed by a space, followed
|
|
|
|
* by the word "{@code throws}" followed by a
|
|
|
|
* comma-separated list of the thrown exception types.
|
|
|
|
*
|
|
|
|
* <p>The only possible modifiers for constructors are the access
|
|
|
|
* modifiers {@code public}, {@code protected} or
|
|
|
|
* {@code private}. Only one of these may appear, or none if the
|
|
|
|
* constructor has default (package) access.
|
|
|
|
*
|
|
|
|
* @return a string describing this {@code Constructor},
|
|
|
|
* include type parameters
|
|
|
|
*
|
|
|
|
* @since 1.5
|
2015-09-24 06:06:07 -04:00
|
|
|
* @jls 8.8.3. Constructor Modifiers
|
2014-08-13 10:39:27 +01:00
|
|
|
*/
|
2015-09-24 06:06:07 -04:00
|
|
|
@Override
|
2014-08-13 10:39:27 +01:00
|
|
|
public String toGenericString() {
|
2015-09-24 06:06:07 -04:00
|
|
|
return sharedToGenericString(Modifier.constructorModifiers(), false);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
void specificToGenericStringHeader(StringBuilder sb) {
|
|
|
|
specificToStringHeader(sb);
|
2014-08-13 10:39:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Uses the constructor represented by this {@code Constructor} object to
|
|
|
|
* create and initialize a new instance of the constructor's
|
|
|
|
* declaring class, with the specified initialization parameters.
|
|
|
|
* Individual parameters are automatically unwrapped to match
|
|
|
|
* primitive formal parameters, and both primitive and reference
|
|
|
|
* parameters are subject to method invocation conversions as necessary.
|
|
|
|
*
|
|
|
|
* <p>If the number of formal parameters required by the underlying constructor
|
|
|
|
* is 0, the supplied {@code initargs} array may be of length 0 or null.
|
|
|
|
*
|
|
|
|
* <p>If the constructor's declaring class is an inner class in a
|
|
|
|
* non-static context, the first argument to the constructor needs
|
|
|
|
* to be the enclosing instance; see section 15.9.3 of
|
|
|
|
* <cite>The Java™ Language Specification</cite>.
|
|
|
|
*
|
|
|
|
* <p>If the required access and argument checks succeed and the
|
|
|
|
* instantiation will proceed, the constructor's declaring class
|
|
|
|
* is initialized if it has not already been initialized.
|
|
|
|
*
|
|
|
|
* <p>If the constructor completes normally, returns the newly
|
|
|
|
* created and initialized instance.
|
|
|
|
*
|
|
|
|
* @param initargs array of objects to be passed as arguments to
|
|
|
|
* the constructor call; values of primitive types are wrapped in
|
|
|
|
* a wrapper object of the appropriate type (e.g. a {@code float}
|
|
|
|
* in a {@link java.lang.Float Float})
|
|
|
|
*
|
|
|
|
* @return a new object created by calling the constructor
|
|
|
|
* this object represents
|
|
|
|
*
|
|
|
|
* @exception IllegalAccessException if this {@code Constructor} object
|
|
|
|
* is enforcing Java language access control and the underlying
|
|
|
|
* constructor is inaccessible.
|
|
|
|
* @exception IllegalArgumentException if the number of actual
|
|
|
|
* and formal parameters differ; if an unwrapping
|
|
|
|
* conversion for primitive arguments fails; or if,
|
|
|
|
* after possible unwrapping, a parameter value
|
|
|
|
* cannot be converted to the corresponding formal
|
|
|
|
* parameter type by a method invocation conversion; if
|
|
|
|
* this constructor pertains to an enum type.
|
|
|
|
* @exception InstantiationException if the class that declares the
|
|
|
|
* underlying constructor represents an abstract class.
|
|
|
|
* @exception InvocationTargetException if the underlying constructor
|
|
|
|
* throws an exception.
|
|
|
|
* @exception ExceptionInInitializerError if the initialization provoked
|
|
|
|
* by this method fails.
|
|
|
|
*/
|
|
|
|
@CallerSensitive
|
|
|
|
public T newInstance(Object ... initargs)
|
|
|
|
throws InstantiationException, IllegalAccessException,
|
|
|
|
IllegalArgumentException, InvocationTargetException
|
|
|
|
{
|
|
|
|
if (!override) {
|
|
|
|
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
|
|
|
|
Class<?> caller = Reflection.getCallerClass();
|
|
|
|
checkAccess(caller, clazz, null, modifiers);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ((clazz.getModifiers() & Modifier.ENUM) != 0)
|
|
|
|
throw new IllegalArgumentException("Cannot reflectively create enum objects");
|
|
|
|
ConstructorAccessor ca = constructorAccessor; // read volatile
|
|
|
|
if (ca == null) {
|
|
|
|
ca = acquireConstructorAccessor();
|
|
|
|
}
|
2015-09-24 06:06:07 -04:00
|
|
|
@SuppressWarnings("unchecked")
|
|
|
|
T inst = (T) ca.newInstance(initargs);
|
|
|
|
return inst;
|
2014-08-13 10:39:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2015-09-24 06:06:07 -04:00
|
|
|
* {@inheritDoc}
|
2014-08-13 10:39:27 +01:00
|
|
|
* @since 1.5
|
|
|
|
*/
|
2015-09-24 06:06:07 -04:00
|
|
|
@Override
|
2014-08-13 10:39:27 +01:00
|
|
|
public boolean isVarArgs() {
|
2015-09-24 06:06:07 -04:00
|
|
|
return super.isVarArgs();
|
2014-08-13 10:39:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2015-09-24 06:06:07 -04:00
|
|
|
* {@inheritDoc}
|
|
|
|
* @jls 13.1 The Form of a Binary
|
2014-08-13 10:39:27 +01:00
|
|
|
* @since 1.5
|
|
|
|
*/
|
2015-09-24 06:06:07 -04:00
|
|
|
@Override
|
2014-08-13 10:39:27 +01:00
|
|
|
public boolean isSynthetic() {
|
2015-09-24 06:06:07 -04:00
|
|
|
return super.isSynthetic();
|
2014-08-13 10:39:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
|
2015-09-24 06:06:07 -04:00
|
|
|
String getSignature() {
|
|
|
|
return signature;
|
|
|
|
}
|
2014-08-13 10:39:27 +01:00
|
|
|
|
|
|
|
byte[] getRawAnnotations() {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
byte[] getRawParameterAnnotations() {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2015-09-24 06:06:07 -04:00
|
|
|
|
2014-08-13 10:39:27 +01:00
|
|
|
/**
|
2015-09-24 06:06:07 -04:00
|
|
|
* {@inheritDoc}
|
|
|
|
* @throws NullPointerException {@inheritDoc}
|
2014-08-13 10:39:27 +01:00
|
|
|
* @since 1.5
|
|
|
|
*/
|
|
|
|
public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
|
2015-09-24 06:06:07 -04:00
|
|
|
return super.getAnnotation(annotationClass);
|
2014-08-13 10:39:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2015-09-24 06:06:07 -04:00
|
|
|
* {@inheritDoc}
|
2014-08-13 10:39:27 +01:00
|
|
|
* @since 1.5
|
|
|
|
*/
|
|
|
|
public Annotation[] getDeclaredAnnotations() {
|
2015-09-24 06:06:07 -04:00
|
|
|
return super.getDeclaredAnnotations();
|
2014-08-13 10:39:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2015-09-24 06:06:07 -04:00
|
|
|
* {@inheritDoc}
|
2014-08-13 10:39:27 +01:00
|
|
|
* @since 1.5
|
|
|
|
*/
|
2015-09-24 06:06:07 -04:00
|
|
|
@Override
|
2014-08-13 10:39:27 +01:00
|
|
|
public Annotation[][] getParameterAnnotations() {
|
2015-09-24 06:06:07 -04:00
|
|
|
return sharedGetParameterAnnotations(parameterTypes);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
void handleParameterNumberMismatch(int resultLength, int numParameters) {
|
|
|
|
Class<?> declaringClass = getDeclaringClass();
|
|
|
|
if (declaringClass.isEnum() ||
|
|
|
|
declaringClass.isAnonymousClass() ||
|
|
|
|
declaringClass.isLocalClass() )
|
|
|
|
return ; // Can't do reliable parameter counting
|
|
|
|
else {
|
|
|
|
if (!declaringClass.isMemberClass() || // top-level
|
|
|
|
// Check for the enclosing instance parameter for
|
|
|
|
// non-static member classes
|
|
|
|
(declaringClass.isMemberClass() &&
|
|
|
|
((declaringClass.getModifiers() & Modifier.STATIC) == 0) &&
|
|
|
|
resultLength + 1 != numParameters) ) {
|
|
|
|
throw new AnnotationFormatError(
|
|
|
|
"Parameter annotations don't match number of parameters");
|
2014-08-13 10:39:27 +01:00
|
|
|
}
|
|
|
|
}
|
2015-09-24 06:06:07 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* {@inheritDoc}
|
|
|
|
* @since 1.8
|
|
|
|
*/
|
|
|
|
@Override
|
|
|
|
public AnnotatedType getAnnotatedReturnType() {
|
|
|
|
return getAnnotatedReturnType0(getDeclaringClass());
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* {@inheritDoc}
|
|
|
|
* @since 1.8
|
|
|
|
*/
|
|
|
|
@Override
|
|
|
|
public AnnotatedType getAnnotatedReceiverType() {
|
|
|
|
if (getDeclaringClass().getEnclosingClass() == null)
|
|
|
|
return super.getAnnotatedReceiverType();
|
|
|
|
|
|
|
|
return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes0(),
|
|
|
|
sun.misc.SharedSecrets.getJavaLangAccess().
|
|
|
|
getConstantPool(getDeclaringClass()),
|
|
|
|
this,
|
|
|
|
getDeclaringClass(),
|
|
|
|
getDeclaringClass().getEnclosingClass(),
|
|
|
|
TypeAnnotation.TypeAnnotationTarget.METHOD_RECEIVER);
|
2014-08-13 10:39:27 +01:00
|
|
|
}
|
|
|
|
}
|