/*
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package java.lang.reflect;
import sun.reflect.
CallerSensitive;
import sun.reflect.
ConstructorAccessor;
import sun.reflect.
Reflection;
import sun.reflect.annotation.
TypeAnnotation;
import sun.reflect.annotation.
TypeAnnotationParser;
import sun.reflect.generics.repository.
ConstructorRepository;
import sun.reflect.generics.factory.
CoreReflectionFactory;
import sun.reflect.generics.factory.
GenericsFactory;
import sun.reflect.generics.scope.
ConstructorScope;
import java.lang.annotation.
Annotation;
import java.lang.annotation.
AnnotationFormatError;
/**
* {@code Constructor} provides information about, and access to, a single
* constructor for a class.
*
* <p>{@code Constructor} permits widening conversions to occur when matching the
* actual parameters to newInstance() with the underlying
* constructor's formal parameters, but throws an
* {@code IllegalArgumentException} if a narrowing conversion would occur.
*
* @param <T> the class in which the constructor is declared
*
* @see Member
* @see java.lang.Class
* @see java.lang.Class#getConstructors()
* @see java.lang.Class#getConstructor(Class[])
* @see java.lang.Class#getDeclaredConstructors()
*
* @author Kenneth Russell
* @author Nakul Saraiya
*/
public final class
Constructor<T> extends
Executable {
private
Class<T>
clazz;
private int
slot;
private
Class<?>[]
parameterTypes;
private
Class<?>[]
exceptionTypes;
private int
modifiers;
// Generics and annotations support
private transient
String signature;
// generic info repository; lazily initialized
private transient
ConstructorRepository genericInfo;
private byte[]
annotations;
private byte[]
parameterAnnotations;
// Generics infrastructure
// Accessor for factory
private
GenericsFactory getFactory() {
// create scope and factory
return
CoreReflectionFactory.
make(this,
ConstructorScope.
make(this));
}
// Accessor for generic info repository
@
Override
ConstructorRepository getGenericInfo() {
// lazily initialize repository if necessary
if (
genericInfo == null) {
// create and cache generic info repository
genericInfo =
ConstructorRepository.
make(
getSignature(),
getFactory());
}
return
genericInfo; //return cached repository
}
private volatile
ConstructorAccessor constructorAccessor;
// For sharing of ConstructorAccessors. This branching structure
// is currently only two levels deep (i.e., one root Constructor
// and potentially many Constructor objects pointing to it.)
//
// If this branching structure would ever contain cycles, deadlocks can
// occur in annotation code.
private
Constructor<T>
root;
/**
* Used by Excecutable for annotation sharing.
*/
@
Override
Executable getRoot() {
return
root;
}
/**
* Package-private constructor used by ReflectAccess to enable
* instantiation of these objects in Java code from the java.lang
* package via sun.reflect.LangReflectAccess.
*/
Constructor(
Class<T>
declaringClass,
Class<?>[]
parameterTypes,
Class<?>[]
checkedExceptions,
int
modifiers,
int
slot,
String signature,
byte[]
annotations,
byte[]
parameterAnnotations) {
this.
clazz =
declaringClass;
this.
parameterTypes =
parameterTypes;
this.
exceptionTypes =
checkedExceptions;
this.
modifiers =
modifiers;
this.
slot =
slot;
this.
signature =
signature;
this.
annotations =
annotations;
this.
parameterAnnotations =
parameterAnnotations;
}
/**
* Package-private routine (exposed to java.lang.Class via
* ReflectAccess) which returns a copy of this Constructor. The copy's
* "root" field points to this Constructor.
*/
Constructor<T>
copy() {
// This routine enables sharing of ConstructorAccessor objects
// among Constructor objects which refer to the same underlying
// method in the VM. (All of this contortion is only necessary
// because of the "accessibility" bit in AccessibleObject,
// which implicitly requires that new java.lang.reflect
// objects be fabricated for each reflective call on Class
// objects.)
if (this.
root != null)
throw new
IllegalArgumentException("Can not copy a non-root Constructor");
Constructor<T>
res = new
Constructor<>(
clazz,
parameterTypes,
exceptionTypes,
modifiers,
slot,
signature,
annotations,
parameterAnnotations);
res.
root = this;
// Might as well eagerly propagate this if already present
res.
constructorAccessor =
constructorAccessor;
return
res;
}
@
Override
boolean
hasGenericInformation() {
return (
getSignature() != null);
}
@
Override
byte[]
getAnnotationBytes() {
return
annotations;
}
/**
* {@inheritDoc}
*/
@
Override
public
Class<T>
getDeclaringClass() {
return
clazz;
}
/**
* Returns the name of this constructor, as a string. This is
* the binary name of the constructor's declaring class.
*/
@
Override
public
String getName() {
return
getDeclaringClass().
getName();
}
/**
* {@inheritDoc}
*/
@
Override
public int
getModifiers() {
return
modifiers;
}
/**
* {@inheritDoc}
* @throws GenericSignatureFormatError {@inheritDoc}
* @since 1.5
*/
@
Override
@
SuppressWarnings({"rawtypes", "unchecked"})
public
TypeVariable<
Constructor<T>>[]
getTypeParameters() {
if (
getSignature() != null) {
return (
TypeVariable<
Constructor<T>>[])
getGenericInfo().
getTypeParameters();
} else
return (
TypeVariable<
Constructor<T>>[])new
TypeVariable[0];
}
/**
* {@inheritDoc}
*/
@
Override
public
Class<?>[]
getParameterTypes() {
return
parameterTypes.
clone();
}
/**
* {@inheritDoc}
* @since 1.8
*/
public int
getParameterCount() { return
parameterTypes.length; }
/**
* {@inheritDoc}
* @throws GenericSignatureFormatError {@inheritDoc}
* @throws TypeNotPresentException {@inheritDoc}
* @throws MalformedParameterizedTypeException {@inheritDoc}
* @since 1.5
*/
@
Override
public
Type[]
getGenericParameterTypes() {
return super.getGenericParameterTypes();
}
/**
* {@inheritDoc}
*/
@
Override
public
Class<?>[]
getExceptionTypes() {
return
exceptionTypes.
clone();
}
/**
* {@inheritDoc}
* @throws GenericSignatureFormatError {@inheritDoc}
* @throws TypeNotPresentException {@inheritDoc}
* @throws MalformedParameterizedTypeException {@inheritDoc}
* @since 1.5
*/
@
Override
public
Type[]
getGenericExceptionTypes() {
return super.getGenericExceptionTypes();
}
/**
* Compares this {@code Constructor} against the specified object.
* Returns true if the objects are the same. Two {@code Constructor} objects are
* the same if they were declared by the same class and have the
* same formal parameter types.
*/
public boolean
equals(
Object obj) {
if (
obj != null &&
obj instanceof
Constructor) {
Constructor<?>
other = (
Constructor<?>)
obj;
if (
getDeclaringClass() ==
other.
getDeclaringClass()) {
return
equalParamTypes(
parameterTypes,
other.
parameterTypes);
}
}
return false;
}
/**
* Returns a hashcode for this {@code Constructor}. The hashcode is
* the same as the hashcode for the underlying constructor's
* declaring class name.
*/
public int
hashCode() {
return
getDeclaringClass().
getName().
hashCode();
}
/**
* Returns a string describing this {@code Constructor}. The string is
* formatted as the constructor access modifiers, if any,
* followed by the fully-qualified name of the declaring class,
* followed by a parenthesized, comma-separated list of the
* constructor's formal parameter types. For example:
* <pre>
* public java.util.Hashtable(int,float)
* </pre>
*
* <p>The only possible modifiers for constructors are the access
* modifiers {@code public}, {@code protected} or
* {@code private}. Only one of these may appear, or none if the
* constructor has default (package) access.
*
* @return a string describing this {@code Constructor}
* @jls 8.8.3. Constructor Modifiers
*/
public
String toString() {
return
sharedToString(
Modifier.
constructorModifiers(),
false,
parameterTypes,
exceptionTypes);
}
@
Override
void
specificToStringHeader(
StringBuilder sb) {
sb.
append(
getDeclaringClass().
getTypeName());
}
/**
* Returns a string describing this {@code Constructor},
* including type parameters. The string is formatted as the
* constructor access modifiers, if any, followed by an
* angle-bracketed comma separated list of the constructor's type
* parameters, if any, followed by the fully-qualified name of the
* declaring class, followed by a parenthesized, comma-separated
* list of the constructor's generic formal parameter types.
*
* If this constructor was declared to take a variable number of
* arguments, instead of denoting the last parameter as
* "<tt><i>Type</i>[]</tt>", it is denoted as
* "<tt><i>Type</i>...</tt>".
*
* A space is used to separate access modifiers from one another
* and from the type parameters or return type. If there are no
* type parameters, the type parameter list is elided; if the type
* parameter list is present, a space separates the list from the
* class name. If the constructor is declared to throw
* exceptions, the parameter list is followed by a space, followed
* by the word "{@code throws}" followed by a
* comma-separated list of the thrown exception types.
*
* <p>The only possible modifiers for constructors are the access
* modifiers {@code public}, {@code protected} or
* {@code private}. Only one of these may appear, or none if the
* constructor has default (package) access.
*
* @return a string describing this {@code Constructor},
* include type parameters
*
* @since 1.5
* @jls 8.8.3. Constructor Modifiers
*/
@
Override
public
String toGenericString() {
return
sharedToGenericString(
Modifier.
constructorModifiers(), false);
}
@
Override
void
specificToGenericStringHeader(
StringBuilder sb) {
specificToStringHeader(
sb);
}
/**
* Uses the constructor represented by this {@code Constructor} object to
* create and initialize a new instance of the constructor's
* declaring class, with the specified initialization parameters.
* Individual parameters are automatically unwrapped to match
* primitive formal parameters, and both primitive and reference
* parameters are subject to method invocation conversions as necessary.
*
* <p>If the number of formal parameters required by the underlying constructor
* is 0, the supplied {@code initargs} array may be of length 0 or null.
*
* <p>If the constructor's declaring class is an inner class in a
* non-static context, the first argument to the constructor needs
* to be the enclosing instance; see section 15.9.3 of
* <cite>The Java™ Language Specification</cite>.
*
* <p>If the required access and argument checks succeed and the
* instantiation will proceed, the constructor's declaring class
* is initialized if it has not already been initialized.
*
* <p>If the constructor completes normally, returns the newly
* created and initialized instance.
*
* @param initargs array of objects to be passed as arguments to
* the constructor call; values of primitive types are wrapped in
* a wrapper object of the appropriate type (e.g. a {@code float}
* in a {@link java.lang.Float Float})
*
* @return a new object created by calling the constructor
* this object represents
*
* @exception IllegalAccessException if this {@code Constructor} object
* is enforcing Java language access control and the underlying
* constructor is inaccessible.
* @exception IllegalArgumentException if the number of actual
* and formal parameters differ; if an unwrapping
* conversion for primitive arguments fails; or if,
* after possible unwrapping, a parameter value
* cannot be converted to the corresponding formal
* parameter type by a method invocation conversion; if
* this constructor pertains to an enum type.
* @exception InstantiationException if the class that declares the
* underlying constructor represents an abstract class.
* @exception InvocationTargetException if the underlying constructor
* throws an exception.
* @exception ExceptionInInitializerError if the initialization provoked
* by this method fails.
*/
@
CallerSensitive
public T
newInstance(
Object ...
initargs)
throws
InstantiationException,
IllegalAccessException,
IllegalArgumentException,
InvocationTargetException
{
if (!
override) {
if (!
Reflection.
quickCheckMemberAccess(
clazz,
modifiers)) {
Class<?>
caller =
Reflection.
getCallerClass();
checkAccess(
caller,
clazz, null,
modifiers);
}
}
if ((
clazz.
getModifiers() &
Modifier.
ENUM) != 0)
throw new
IllegalArgumentException("Cannot reflectively create enum objects");
ConstructorAccessor ca =
constructorAccessor; // read volatile
if (
ca == null) {
ca =
acquireConstructorAccessor();
}
@
SuppressWarnings("unchecked")
T
inst = (T)
ca.
newInstance(
initargs);
return
inst;
}
/**
* {@inheritDoc}
* @since 1.5
*/
@
Override
public boolean
isVarArgs() {
return super.isVarArgs();
}
/**
* {@inheritDoc}
* @jls 13.1 The Form of a Binary
* @since 1.5
*/
@
Override
public boolean
isSynthetic() {
return super.isSynthetic();
}
// NOTE that there is no synchronization used here. It is correct
// (though not efficient) to generate more than one
// ConstructorAccessor for a given Constructor. However, avoiding
// synchronization will probably make the implementation more
// scalable.
private
ConstructorAccessor acquireConstructorAccessor() {
// First check to see if one has been created yet, and take it
// if so.
ConstructorAccessor tmp = null;
if (
root != null)
tmp =
root.
getConstructorAccessor();
if (
tmp != null) {
constructorAccessor =
tmp;
} else {
// Otherwise fabricate one and propagate it up to the root
tmp =
reflectionFactory.
newConstructorAccessor(this);
setConstructorAccessor(
tmp);
}
return
tmp;
}
// Returns ConstructorAccessor for this Constructor object, not
// looking up the chain to the root
ConstructorAccessor getConstructorAccessor() {
return
constructorAccessor;
}
// Sets the ConstructorAccessor for this Constructor object and
// (recursively) its root
void
setConstructorAccessor(
ConstructorAccessor accessor) {
constructorAccessor =
accessor;
// Propagate up
if (
root != null) {
root.
setConstructorAccessor(
accessor);
}
}
int
getSlot() {
return
slot;
}
String getSignature() {
return
signature;
}
byte[]
getRawAnnotations() {
return
annotations;
}
byte[]
getRawParameterAnnotations() {
return
parameterAnnotations;
}
/**
* {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
* @since 1.5
*/
public <T extends
Annotation> T
getAnnotation(
Class<T>
annotationClass) {
return super.getAnnotation(
annotationClass);
}
/**
* {@inheritDoc}
* @since 1.5
*/
public
Annotation[]
getDeclaredAnnotations() {
return super.getDeclaredAnnotations();
}
/**
* {@inheritDoc}
* @since 1.5
*/
@
Override
public
Annotation[][]
getParameterAnnotations() {
return
sharedGetParameterAnnotations(
parameterTypes,
parameterAnnotations);
}
@
Override
void
handleParameterNumberMismatch(int
resultLength, int
numParameters) {
Class<?>
declaringClass =
getDeclaringClass();
if (
declaringClass.
isEnum() ||
declaringClass.
isAnonymousClass() ||
declaringClass.
isLocalClass() )
return ; // Can't do reliable parameter counting
else {
if (!
declaringClass.
isMemberClass() || // top-level
// Check for the enclosing instance parameter for
// non-static member classes
(
declaringClass.
isMemberClass() &&
((
declaringClass.
getModifiers() &
Modifier.
STATIC) == 0) &&
resultLength + 1 !=
numParameters) ) {
throw new
AnnotationFormatError(
"Parameter annotations don't match number of parameters");
}
}
}
/**
* {@inheritDoc}
* @since 1.8
*/
@
Override
public
AnnotatedType getAnnotatedReturnType() {
return
getAnnotatedReturnType0(
getDeclaringClass());
}
/**
* {@inheritDoc}
* @since 1.8
*/
@
Override
public
AnnotatedType getAnnotatedReceiverType() {
if (
getDeclaringClass().
getEnclosingClass() == null)
return super.getAnnotatedReceiverType();
return
TypeAnnotationParser.
buildAnnotatedType(
getTypeAnnotationBytes0(),
sun.misc.
SharedSecrets.
getJavaLangAccess().
getConstantPool(
getDeclaringClass()),
this,
getDeclaringClass(),
getDeclaringClass().
getEnclosingClass(),
TypeAnnotation.
TypeAnnotationTarget.
METHOD_RECEIVER);
}
}