| /* | |
| * Copyright (c) 1996, 2025, 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.access.SharedSecrets; | |
| import jdk.internal.misc.VM; | |
| import jdk.internal.reflect.CallerSensitive; | |
| import jdk.internal.reflect.ConstructorAccessor; | |
| import jdk.internal.reflect.Reflection; | |
| import jdk.internal.vm.annotation.ForceInline; | |
| import jdk.internal.vm.annotation.Stable; | |
| import sun.reflect.annotation.TypeAnnotation; | |
| import sun.reflect.annotation.TypeAnnotationParser; | |
| import sun.reflect.generics.repository.ConstructorRepository; | |
| import sun.reflect.generics.repository.GenericDeclRepository; | |
| 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 final Class<T> clazz; | |
| private final int slot; | |
| private final Class<?>[] parameterTypes; | |
| private final Class<?>[] exceptionTypes; | |
| private final int modifiers; | |
| // Generics and annotations support | |
| private final transient String signature; | |
| private final byte[] annotations; | |
| private final 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() { | |
| var genericInfo = this.genericInfo; | |
| if (genericInfo == null) { | |
| var root = this.root; | |
| if (root != null) { | |
| genericInfo = root.getGenericInfo(); | |
| } else { | |
| genericInfo = ConstructorRepository.make(getSignature(), getFactory()); | |
| } | |
| this.genericInfo = genericInfo; | |
| } | |
| return genericInfo; | |
| } | |
| /** | |
| * Constructors are mutable due to {@link AccessibleObject#setAccessible(boolean)}. | |
| * Thus, we return a new copy of a root each time a constructor is returned. | |
| * Some lazily initialized immutable states can be stored on root and shared to the copies. | |
| */ | |
| private Constructor<T> root; | |
| private transient volatile ConstructorRepository genericInfo; | |
| private @Stable ConstructorAccessor constructorAccessor; | |
| // End shared states | |
| @Override | |
| Constructor<T> getRoot() { | |
| return root; | |
| } | |
| /** | |
| * Package-private constructor used by ReflectAccess to enable | |
| * instantiation of these objects in Java code from the java.lang | |
| * package via jdk.internal.access.JavaLangReflectAccess. | |
| */ | |
| 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() { | |
| 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; | |
| res.genericInfo = genericInfo; | |
| return res; | |
| } | |
| // Creates a new root constructor with a custom accessor for serialization hooks. | |
| Constructor<T> newWithAccessor(ConstructorAccessor accessor) { | |
| var res = new Constructor<>(clazz, parameterTypes, exceptionTypes, modifiers, slot, | |
| signature, annotations, parameterAnnotations); | |
| res.constructorAccessor = accessor; | |
| return res; | |
| } | |
| /** | |
| * {@inheritDoc} | |
| * | |
| * <p> A {@code SecurityException} is 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 this is a constructor for {@code java.lang.Class} | |
| */ | |
| @Override | |
| @CallerSensitive | |
| public void setAccessible(boolean flag) { | |
| 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} | |
| * @jls 8.8.3 Constructor Modifiers | |
| */ | |
| @Override | |
| public int getModifiers() { | |
| return modifiers; | |
| } | |
| /** | |
| * {@inheritDoc} | |
| * @throws GenericSignatureFormatError {@inheritDoc} | |
| * @since 1.5 | |
| */ | |
| @Override | |
| @SuppressWarnings("unchecked") | |
| public TypeVariable<Constructor<T>>[] getTypeParameters() { | |
| if (getSignature() != null) { | |
| return (TypeVariable<Constructor<T>>[])getGenericInfo().getTypeParameters(); | |
| } else | |
| return (TypeVariable<Constructor<T>>[])GenericDeclRepository.EMPTY_TYPE_VARS; | |
| } | |
| @Override | |
| Class<?>[] getSharedParameterTypes() { | |
| return parameterTypes; | |
| } | |
| @Override | |
| Class<?>[] getSharedExceptionTypes() { | |
| return exceptionTypes; | |
| } | |
| /** | |
| * {@inheritDoc} | |
| */ | |
| @Override | |
| public Class<?>[] getParameterTypes() { | |
| return parameterTypes.length == 0 ? parameterTypes : 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.length == 0 ? exceptionTypes : 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 instanceof Constructor<?> other) { | |
| 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.HashMap(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 : getSharedParameterTypes()) { | |
| 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, including informative bounds of the | |
| * 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 {@jls 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 | |
| * | |
| * @throws IllegalAccessException if this {@code Constructor} object | |
| * is enforcing Java language access control and the underlying | |
| * constructor is inaccessible. | |
| * @throws 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 class. | |
| * @throws InstantiationException if the class that declares the | |
| * underlying constructor represents an abstract class. | |
| * @throws InvocationTargetException if the underlying constructor | |
| * throws an exception. | |
| * @throws 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 | |
| { | |
| Class<?> caller = override ? null : Reflection.getCallerClass(); | |
| return newInstanceWithCaller(initargs, !override, caller); | |
| } | |
| /* package-private */ | |
| T newInstanceWithCaller(Object[] args, boolean checkAccess, Class<?> caller) | |
| throws InstantiationException, IllegalAccessException, | |
| InvocationTargetException | |
| { | |
| if (checkAccess) | |
| checkAccess(caller, clazz, clazz, modifiers); | |
| ConstructorAccessor ca = constructorAccessor; // read @Stable | |
| if (ca == null) { | |
| ca = acquireConstructorAccessor(); | |
| } | |
| @SuppressWarnings("unchecked") | |
| T inst = (T) ca.newInstance(args); | |
| return inst; | |
| } | |
| /** | |
| * {@inheritDoc} | |
| * @since 1.5 | |
| * @jls 8.4.1 Formal Parameters | |
| */ | |
| @Override | |
| public boolean isVarArgs() { | |
| return super.isVarArgs(); | |
| } | |
| /** | |
| * {@inheritDoc} | |
| * @jls 13.1 The Form of a Binary | |
| * @jvms 4.6 Methods | |
| * @since 1.5 | |
| * @see <a | |
| * href="{@docRoot}/java.base/java/lang/reflect/package-summary.html#LanguageJvmModel">Java | |
| * programming language and JVM modeling in core reflection</a> | |
| */ | |
| @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. | |
| Constructor<?> root = this.root; | |
| ConstructorAccessor tmp = root == null ? null : root.getConstructorAccessor(); | |
| if (tmp != null) { | |
| constructorAccessor = tmp; | |
| } else { | |
| // Otherwise fabricate one and propagate it up to the root | |
| // Ensure the declaring class is not an Enum class. | |
| if ((clazz.getModifiers() & Modifier.ENUM) != 0) | |
| throw new IllegalArgumentException("Cannot reflectively create enum objects"); | |
| tmp = reflectionFactory.newConstructorAccessor(this); | |
| // set the constructor accessor only if it's not using native implementation | |
| if (VM.isJavaLangInvokeInited()) | |
| 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 | |
| Constructor<?> root = this.root; | |
| 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 | |
| */ | |
| @Override | |
| public <T extends Annotation> T getAnnotation(Class<T> annotationClass) { | |
| return super.getAnnotation(annotationClass); | |
| } | |
| /** | |
| * {@inheritDoc} | |
| * @since 1.5 | |
| */ | |
| @Override | |
| public Annotation[] getDeclaredAnnotations() { | |
| return super.getDeclaredAnnotations(); | |
| } | |
| /** | |
| * {@inheritDoc} | |
| * @since 1.5 | |
| */ | |
| @Override | |
| public Annotation[][] getParameterAnnotations() { | |
| return sharedGetParameterAnnotations(parameterTypes, parameterAnnotations); | |
| } | |
| @Override | |
| boolean handleParameterNumberMismatch(int resultLength, Class<?>[] parameterTypes) { | |
| int numParameters = parameterTypes.length; | |
| Class<?> declaringClass = getDeclaringClass(); | |
| if (declaringClass.isEnum()) { | |
| return resultLength + 2 == numParameters && | |
| parameterTypes[0] == String.class && | |
| parameterTypes[1] == int.class; | |
| } else if ( | |
| 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, | |
| parameterize(enclosingClass), | |
| TypeAnnotation.TypeAnnotationTarget.METHOD_RECEIVER); | |
| } | |
| } |