Showing the changes to java/pkg/java/lang/reflect (48 of 18352 files). Show all
Unified · Split
Binary file not shown.
| @@ -0,0 +1,274 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.lang.reflect; | |
| 27 | + | |
| 28 | +import java.security.AccessController; | |
| 29 | +import sun.reflect.Reflection; | |
| 30 | +import sun.reflect.ReflectionFactory; | |
| 31 | +import java.lang.annotation.Annotation; | |
| 32 | + | |
| 33 | +/** | |
| 34 | + * The AccessibleObject class is the base class for Field, Method and | |
| 35 | + * Constructor objects. It provides the ability to flag a reflected | |
| 36 | + * object as suppressing default Java language access control checks | |
| 37 | + * when it is used. The access checks--for public, default (package) | |
| 38 | + * access, protected, and private members--are performed when Fields, | |
| 39 | + * Methods or Constructors are used to set or get fields, to invoke | |
| 40 | + * methods, or to create and initialize new instances of classes, | |
| 41 | + * respectively. | |
| 42 | + * | |
| 43 | + * <p>Setting the {@code accessible} flag in a reflected object | |
| 44 | + * permits sophisticated applications with sufficient privilege, such | |
| 45 | + * as Java Object Serialization or other persistence mechanisms, to | |
| 46 | + * manipulate objects in a manner that would normally be prohibited. | |
| 47 | + * | |
| 48 | + * <p>By default, a reflected object is <em>not</em> accessible. | |
| 49 | + * | |
| 50 | + * @see Field | |
| 51 | + * @see Method | |
| 52 | + * @see Constructor | |
| 53 | + * @see ReflectPermission | |
| 54 | + * | |
| 55 | + * @since 1.2 | |
| 56 | + */ | |
| 57 | +public class AccessibleObject implements AnnotatedElement { | |
| 58 | + | |
| 59 | + /** | |
| 60 | + * The Permission object that is used to check whether a client | |
| 61 | + * has sufficient privilege to defeat Java language access | |
| 62 | + * control checks. | |
| 63 | + */ | |
| 64 | + static final private java.security.Permission ACCESS_PERMISSION = | |
| 65 | + new ReflectPermission("suppressAccessChecks"); | |
| 66 | + | |
| 67 | + /** | |
| 68 | + * Convenience method to set the {@code accessible} flag for an | |
| 69 | + * array of objects with a single security check (for efficiency). | |
| 70 | + * | |
| 71 | + * <p>First, if there is a security manager, its | |
| 72 | + * {@code checkPermission} method is called with a | |
| 73 | + * {@code ReflectPermission("suppressAccessChecks")} permission. | |
| 74 | + * | |
| 75 | + * <p>A {@code SecurityException} is raised if {@code flag} is | |
| 76 | + * {@code true} but accessibility of any of the elements of the input | |
| 77 | + * {@code array} may not be changed (for example, if the element | |
| 78 | + * object is a {@link Constructor} object for the class {@link | |
| 79 | + * java.lang.Class}). In the event of such a SecurityException, the | |
| 80 | + * accessibility of objects is set to {@code flag} for array elements | |
| 81 | + * upto (and excluding) the element for which the exception occurred; the | |
| 82 | + * accessibility of elements beyond (and including) the element for which | |
| 83 | + * the exception occurred is unchanged. | |
| 84 | + * | |
| 85 | + * @param array the array of AccessibleObjects | |
| 86 | + * @param flag the new value for the {@code accessible} flag | |
| 87 | + * in each object | |
| 88 | + * @throws SecurityException if the request is denied. | |
| 89 | + * @see SecurityManager#checkPermission | |
| 90 | + * @see java.lang.RuntimePermission | |
| 91 | + */ | |
| 92 | + public static void setAccessible(AccessibleObject[] array, boolean flag) | |
| 93 | + throws SecurityException { | |
| 94 | + SecurityManager sm = System.getSecurityManager(); | |
| 95 | + if (sm != null) sm.checkPermission(ACCESS_PERMISSION); | |
| 96 | + for (int i = 0; i < array.length; i++) { | |
| 97 | + setAccessible0(array[i], flag); | |
| 98 | + } | |
| 99 | + } | |
| 100 | + | |
| 101 | + /** | |
| 102 | + * Set the {@code accessible} flag for this object to | |
| 103 | + * the indicated boolean value. A value of {@code true} indicates that | |
| 104 | + * the reflected object should suppress Java language access | |
| 105 | + * checking when it is used. A value of {@code false} indicates | |
| 106 | + * that the reflected object should enforce Java language access checks. | |
| 107 | + * | |
| 108 | + * <p>First, if there is a security manager, its | |
| 109 | + * {@code checkPermission} method is called with a | |
| 110 | + * {@code ReflectPermission("suppressAccessChecks")} permission. | |
| 111 | + * | |
| 112 | + * <p>A {@code SecurityException} is raised if {@code flag} is | |
| 113 | + * {@code true} but accessibility of this object may not be changed | |
| 114 | + * (for example, if this element object is a {@link Constructor} object for | |
| 115 | + * the class {@link java.lang.Class}). | |
| 116 | + * | |
| 117 | + * <p>A {@code SecurityException} is raised if this object is a {@link | |
| 118 | + * java.lang.reflect.Constructor} object for the class | |
| 119 | + * {@code java.lang.Class}, and {@code flag} is true. | |
| 120 | + * | |
| 121 | + * @param flag the new value for the {@code accessible} flag | |
| 122 | + * @throws SecurityException if the request is denied. | |
| 123 | + * @see SecurityManager#checkPermission | |
| 124 | + * @see java.lang.RuntimePermission | |
| 125 | + */ | |
| 126 | + public void setAccessible(boolean flag) throws SecurityException { | |
| 127 | + SecurityManager sm = System.getSecurityManager(); | |
| 128 | + if (sm != null) sm.checkPermission(ACCESS_PERMISSION); | |
| 129 | + setAccessible0(this, flag); | |
| 130 | + } | |
| 131 | + | |
| 132 | + /* Check that you aren't exposing java.lang.Class.<init>. */ | |
| 133 | + private static void setAccessible0(AccessibleObject obj, boolean flag) | |
| 134 | + throws SecurityException | |
| 135 | + { | |
| 136 | + if (obj instanceof Constructor && flag == true) { | |
| 137 | + Constructor<?> c = (Constructor<?>)obj; | |
| 138 | + if (c.getDeclaringClass() == Class.class) { | |
| 139 | + throw new SecurityException("Can not make a java.lang.Class" + | |
| 140 | + " constructor accessible"); | |
| 141 | + } | |
| 142 | + } | |
| 143 | + obj.override = flag; | |
| 144 | + } | |
| 145 | + | |
| 146 | + /** | |
| 147 | + * Get the value of the {@code accessible} flag for this object. | |
| 148 | + * | |
| 149 | + * @return the value of the object's {@code accessible} flag | |
| 150 | + */ | |
| 151 | + public boolean isAccessible() { | |
| 152 | + return override; | |
| 153 | + } | |
| 154 | + | |
| 155 | + /** | |
| 156 | + * Constructor: only used by the Java Virtual Machine. | |
| 157 | + */ | |
| 158 | + protected AccessibleObject() {} | |
| 159 | + | |
| 160 | + // Indicates whether language-level access checks are overridden | |
| 161 | + // by this object. Initializes to "false". This field is used by | |
| 162 | + // Field, Method, and Constructor. | |
| 163 | + // | |
| 164 | + // NOTE: for security purposes, this field must not be visible | |
| 165 | + // outside this package. | |
| 166 | + boolean override; | |
| 167 | + | |
| 168 | + // Reflection factory used by subclasses for creating field, | |
| 169 | + // method, and constructor accessors. Note that this is called | |
| 170 | + // very early in the bootstrapping process. | |
| 171 | + static final ReflectionFactory reflectionFactory = | |
| 172 | + AccessController.doPrivileged( | |
| 173 | + new sun.reflect.ReflectionFactory.GetReflectionFactoryAction()); | |
| 174 | + | |
| 175 | + /** | |
| 176 | + * @throws NullPointerException {@inheritDoc} | |
| 177 | + * @since 1.5 | |
| 178 | + */ | |
| 179 | + public <T extends Annotation> T getAnnotation(Class<T> annotationClass) { | |
| 180 | + throw new AssertionError("All subclasses should override this method"); | |
| 181 | + } | |
| 182 | + | |
| 183 | + /** | |
| 184 | + * @throws NullPointerException {@inheritDoc} | |
| 185 | + * @since 1.5 | |
| 186 | + */ | |
| 187 | + public boolean isAnnotationPresent( | |
| 188 | + Class<? extends Annotation> annotationClass) { | |
| 189 | + return getAnnotation(annotationClass) != null; | |
| 190 | + } | |
| 191 | + | |
| 192 | + /** | |
| 193 | + * @since 1.5 | |
| 194 | + */ | |
| 195 | + public Annotation[] getAnnotations() { | |
| 196 | + return getDeclaredAnnotations(); | |
| 197 | + } | |
| 198 | + | |
| 199 | + /** | |
| 200 | + * @since 1.5 | |
| 201 | + */ | |
| 202 | + public Annotation[] getDeclaredAnnotations() { | |
| 203 | + throw new AssertionError("All subclasses should override this method"); | |
| 204 | + } | |
| 205 | + | |
| 206 | + | |
| 207 | + // Shared access checking logic. | |
| 208 | + | |
| 209 | + // For non-public members or members in package-private classes, | |
| 210 | + // it is necessary to perform somewhat expensive security checks. | |
| 211 | + // If the security check succeeds for a given class, it will | |
| 212 | + // always succeed (it is not affected by the granting or revoking | |
| 213 | + // of permissions); we speed up the check in the common case by | |
| 214 | + // remembering the last Class for which the check succeeded. | |
| 215 | + // | |
| 216 | + // The simple security check for Constructor is to see if | |
| 217 | + // the caller has already been seen, verified, and cached. | |
| 218 | + // (See also Class.newInstance(), which uses a similar method.) | |
| 219 | + // | |
| 220 | + // A more complicated security check cache is needed for Method and Field | |
| 221 | + // The cache can be either null (empty cache), a 2-array of {caller,target}, | |
| 222 | + // or a caller (with target implicitly equal to this.clazz). | |
| 223 | + // In the 2-array case, the target is always different from the clazz. | |
| 224 | + volatile Object securityCheckCache; | |
| 225 | + | |
| 226 | + void checkAccess(Class<?> caller, Class<?> clazz, Object obj, int modifiers) | |
| 227 | + throws IllegalAccessException | |
| 228 | + { | |
| 229 | + if (caller == clazz) { // quick check | |
| 230 | + return; // ACCESS IS OK | |
| 231 | + } | |
| 232 | + Object cache = securityCheckCache; // read volatile | |
| 233 | + Class<?> targetClass = clazz; | |
| 234 | + if (obj != null | |
| 235 | + && Modifier.isProtected(modifiers) | |
| 236 | + && ((targetClass = obj.getClass()) != clazz)) { | |
| 237 | + // Must match a 2-list of { caller, targetClass }. | |
| 238 | + if (cache instanceof Class[]) { | |
| 239 | + Class<?>[] cache2 = (Class<?>[]) cache; | |
| 240 | + if (cache2[1] == targetClass && | |
| 241 | + cache2[0] == caller) { | |
| 242 | + return; // ACCESS IS OK | |
| 243 | + } | |
| 244 | + // (Test cache[1] first since range check for [1] | |
| 245 | + // subsumes range check for [0].) | |
| 246 | + } | |
| 247 | + } else if (cache == caller) { | |
| 248 | + // Non-protected case (or obj.class == this.clazz). | |
| 249 | + return; // ACCESS IS OK | |
| 250 | + } | |
| 251 | + | |
| 252 | + // If no return, fall through to the slow path. | |
| 253 | + slowCheckMemberAccess(caller, clazz, obj, modifiers, targetClass); | |
| 254 | + } | |
| 255 | + | |
| 256 | + // Keep all this slow stuff out of line: | |
| 257 | + void slowCheckMemberAccess(Class<?> caller, Class<?> clazz, Object obj, int modifiers, | |
| 258 | + Class<?> targetClass) | |
| 259 | + throws IllegalAccessException | |
| 260 | + { | |
| 261 | + Reflection.ensureMemberAccess(caller, clazz, obj, modifiers); | |
| 262 | + | |
| 263 | + // Success: Update the cache. | |
| 264 | + Object cache = ((targetClass == clazz) | |
| 265 | + ? caller | |
| 266 | + : new Class<?>[] { caller, targetClass }); | |
| 267 | + | |
| 268 | + // Note: The two cache elements are not volatile, | |
| 269 | + // but they are effectively final. The Java memory model | |
| 270 | + // guarantees that the initializing stores for the cache | |
| 271 | + // elements will occur before the volatile write. | |
| 272 | + securityCheckCache = cache; // write volatile | |
| 273 | + } | |
| 274 | +} | |
Binary file not shown.
| @@ -0,0 +1,112 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.lang.reflect; | |
| 27 | + | |
| 28 | +import java.lang.annotation.Annotation; | |
| 29 | + | |
| 30 | +/** | |
| 31 | + * Represents an annotated element of the program currently running in this | |
| 32 | + * VM. This interface allows annotations to be read reflectively. All | |
| 33 | + * annotations returned by methods in this interface are immutable and | |
| 34 | + * serializable. It is permissible for the caller to modify the | |
| 35 | + * arrays returned by accessors for array-valued enum members; it will | |
| 36 | + * have no affect on the arrays returned to other callers. | |
| 37 | + * | |
| 38 | + * <p>If an annotation returned by a method in this interface contains | |
| 39 | + * (directly or indirectly) a {@link Class}-valued member referring to | |
| 40 | + * a class that is not accessible in this VM, attempting to read the class | |
| 41 | + * by calling the relevant Class-returning method on the returned annotation | |
| 42 | + * will result in a {@link TypeNotPresentException}. | |
| 43 | + * | |
| 44 | + * <p>Similarly, attempting to read an enum-valued member will result in | |
| 45 | + * a {@link EnumConstantNotPresentException} if the enum constant in the | |
| 46 | + * annotation is no longer present in the enum type. | |
| 47 | + * | |
| 48 | + * <p>Finally, Attempting to read a member whose definition has evolved | |
| 49 | + * incompatibly will result in a {@link | |
| 50 | + * java.lang.annotation.AnnotationTypeMismatchException} or an | |
| 51 | + * {@link java.lang.annotation.IncompleteAnnotationException}. | |
| 52 | + * | |
| 53 | + * @see java.lang.EnumConstantNotPresentException | |
| 54 | + * @see java.lang.TypeNotPresentException | |
| 55 | + * @see java.lang.annotation.AnnotationFormatError | |
| 56 | + * @see java.lang.annotation.AnnotationTypeMismatchException | |
| 57 | + * @see java.lang.annotation.IncompleteAnnotationException | |
| 58 | + * @since 1.5 | |
| 59 | + * @author Josh Bloch | |
| 60 | + */ | |
| 61 | +public interface AnnotatedElement { | |
| 62 | + /** | |
| 63 | + * Returns true if an annotation for the specified type | |
| 64 | + * is present on this element, else false. This method | |
| 65 | + * is designed primarily for convenient access to marker annotations. | |
| 66 | + * | |
| 67 | + * @param annotationClass the Class object corresponding to the | |
| 68 | + * annotation type | |
| 69 | + * @return true if an annotation for the specified annotation | |
| 70 | + * type is present on this element, else false | |
| 71 | + * @throws NullPointerException if the given annotation class is null | |
| 72 | + * @since 1.5 | |
| 73 | + */ | |
| 74 | + boolean isAnnotationPresent(Class<? extends Annotation> annotationClass); | |
| 75 | + | |
| 76 | + /** | |
| 77 | + * Returns this element's annotation for the specified type if | |
| 78 | + * such an annotation is present, else null. | |
| 79 | + * | |
| 80 | + * @param annotationClass the Class object corresponding to the | |
| 81 | + * annotation type | |
| 82 | + * @return this element's annotation for the specified annotation type if | |
| 83 | + * present on this element, else null | |
| 84 | + * @throws NullPointerException if the given annotation class is null | |
| 85 | + * @since 1.5 | |
| 86 | + */ | |
| 87 | + <T extends Annotation> T getAnnotation(Class<T> annotationClass); | |
| 88 | + | |
| 89 | + /** | |
| 90 | + * Returns all annotations present on this element. (Returns an array | |
| 91 | + * of length zero if this element has no annotations.) The caller of | |
| 92 | + * this method is free to modify the returned array; it will have no | |
| 93 | + * effect on the arrays returned to other callers. | |
| 94 | + * | |
| 95 | + * @return all annotations present on this element | |
| 96 | + * @since 1.5 | |
| 97 | + */ | |
| 98 | + Annotation[] getAnnotations(); | |
| 99 | + | |
| 100 | + /** | |
| 101 | + * Returns all annotations that are directly present on this | |
| 102 | + * element. Unlike the other methods in this interface, this method | |
| 103 | + * ignores inherited annotations. (Returns an array of length zero if | |
| 104 | + * no annotations are directly present on this element.) The caller of | |
| 105 | + * this method is free to modify the returned array; it will have no | |
| 106 | + * effect on the arrays returned to other callers. | |
| 107 | + * | |
| 108 | + * @return All annotations directly present on this element | |
| 109 | + * @since 1.5 | |
| 110 | + */ | |
| 111 | + Annotation[] getDeclaredAnnotations(); | |
| 112 | +} | |
Binary file not shown.
| @@ -0,0 +1,485 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.lang.reflect; | |
| 27 | + | |
| 28 | +/** | |
| 29 | + * The {@code Array} class provides static methods to dynamically create and | |
| 30 | + * access Java arrays. | |
| 31 | + * | |
| 32 | + * <p>{@code Array} permits widening conversions to occur during a get or set | |
| 33 | + * operation, but throws an {@code IllegalArgumentException} if a narrowing | |
| 34 | + * conversion would occur. | |
| 35 | + * | |
| 36 | + * @author Nakul Saraiya | |
| 37 | + */ | |
| 38 | +public final | |
| 39 | +class Array { | |
| 40 | + | |
| 41 | + /** | |
| 42 | + * Constructor. Class Array is not instantiable. | |
| 43 | + */ | |
| 44 | + private Array() {} | |
| 45 | + | |
| 46 | + /** | |
| 47 | + * Creates a new array with the specified component type and | |
| 48 | + * length. | |
| 49 | + * Invoking this method is equivalent to creating an array | |
| 50 | + * as follows: | |
| 51 | + * <blockquote> | |
| 52 | + * <pre> | |
| 53 | + * int[] x = {length}; | |
| 54 | + * Array.newInstance(componentType, x); | |
| 55 | + * </pre> | |
| 56 | + * </blockquote> | |
| 57 | + * | |
| 58 | + * @param componentType the {@code Class} object representing the | |
| 59 | + * component type of the new array | |
| 60 | + * @param length the length of the new array | |
| 61 | + * @return the new array | |
| 62 | + * @exception NullPointerException if the specified | |
| 63 | + * {@code componentType} parameter is null | |
| 64 | + * @exception IllegalArgumentException if componentType is {@link Void#TYPE} | |
| 65 | + * @exception NegativeArraySizeException if the specified {@code length} | |
| 66 | + * is negative | |
| 67 | + */ | |
| 68 | + public static Object newInstance(Class<?> componentType, int length) | |
| 69 | + throws NegativeArraySizeException { | |
| 70 | + return newArray(componentType, length); | |
| 71 | + } | |
| 72 | + | |
| 73 | + /** | |
| 74 | + * Creates a new array | |
| 75 | + * with the specified component type and dimensions. | |
| 76 | + * If {@code componentType} | |
| 77 | + * represents a non-array class or interface, the new array | |
| 78 | + * has {@code dimensions.length} dimensions and | |
| 79 | + * {@code componentType} as its component type. If | |
| 80 | + * {@code componentType} represents an array class, the | |
| 81 | + * number of dimensions of the new array is equal to the sum | |
| 82 | + * of {@code dimensions.length} and the number of | |
| 83 | + * dimensions of {@code componentType}. In this case, the | |
| 84 | + * component type of the new array is the component type of | |
| 85 | + * {@code componentType}. | |
| 86 | + * | |
| 87 | + * <p>The number of dimensions of the new array must not | |
| 88 | + * exceed the number of array dimensions supported by the | |
| 89 | + * implementation (typically 255). | |
| 90 | + * | |
| 91 | + * @param componentType the {@code Class} object representing the component | |
| 92 | + * type of the new array | |
| 93 | + * @param dimensions an array of {@code int} representing the dimensions of | |
| 94 | + * the new array | |
| 95 | + * @return the new array | |
| 96 | + * @exception NullPointerException if the specified | |
| 97 | + * {@code componentType} argument is null | |
| 98 | + * @exception IllegalArgumentException if the specified {@code dimensions} | |
| 99 | + * argument is a zero-dimensional array, or if the number of | |
| 100 | + * requested dimensions exceeds the limit on the number of array dimensions | |
| 101 | + * supported by the implementation (typically 255), or if componentType | |
| 102 | + * is {@link Void#TYPE}. | |
| 103 | + * @exception NegativeArraySizeException if any of the components in | |
| 104 | + * the specified {@code dimensions} argument is negative. | |
| 105 | + */ | |
| 106 | + public static Object newInstance(Class<?> componentType, int... dimensions) | |
| 107 | + throws IllegalArgumentException, NegativeArraySizeException { | |
| 108 | + return multiNewArray(componentType, dimensions); | |
| 109 | + } | |
| 110 | + | |
| 111 | + /** | |
| 112 | + * Returns the length of the specified array object, as an {@code int}. | |
| 113 | + * | |
| 114 | + * @param array the array | |
| 115 | + * @return the length of the array | |
| 116 | + * @exception IllegalArgumentException if the object argument is not | |
| 117 | + * an array | |
| 118 | + */ | |
| 119 | + public static native int getLength(Object array) | |
| 120 | + throws IllegalArgumentException; | |
| 121 | + | |
| 122 | + /** | |
| 123 | + * Returns the value of the indexed component in the specified | |
| 124 | + * array object. The value is automatically wrapped in an object | |
| 125 | + * if it has a primitive type. | |
| 126 | + * | |
| 127 | + * @param array the array | |
| 128 | + * @param index the index | |
| 129 | + * @return the (possibly wrapped) value of the indexed component in | |
| 130 | + * the specified array | |
| 131 | + * @exception NullPointerException If the specified object is null | |
| 132 | + * @exception IllegalArgumentException If the specified object is not | |
| 133 | + * an array | |
| 134 | + * @exception ArrayIndexOutOfBoundsException If the specified {@code index} | |
| 135 | + * argument is negative, or if it is greater than or equal to the | |
| 136 | + * length of the specified array | |
| 137 | + */ | |
| 138 | + public static native Object get(Object array, int index) | |
| 139 | + throws IllegalArgumentException, ArrayIndexOutOfBoundsException; | |
| 140 | + | |
| 141 | + /** | |
| 142 | + * Returns the value of the indexed component in the specified | |
| 143 | + * array object, as a {@code boolean}. | |
| 144 | + * | |
| 145 | + * @param array the array | |
| 146 | + * @param index the index | |
| 147 | + * @return the value of the indexed component in the specified array | |
| 148 | + * @exception NullPointerException If the specified object is null | |
| 149 | + * @exception IllegalArgumentException If the specified object is not | |
| 150 | + * an array, or if the indexed element cannot be converted to the | |
| 151 | + * return type by an identity or widening conversion | |
| 152 | + * @exception ArrayIndexOutOfBoundsException If the specified {@code index} | |
| 153 | + * argument is negative, or if it is greater than or equal to the | |
| 154 | + * length of the specified array | |
| 155 | + * @see Array#get | |
| 156 | + */ | |
| 157 | + public static native boolean getBoolean(Object array, int index) | |
| 158 | + throws IllegalArgumentException, ArrayIndexOutOfBoundsException; | |
| 159 | + | |
| 160 | + /** | |
| 161 | + * Returns the value of the indexed component in the specified | |
| 162 | + * array object, as a {@code byte}. | |
| 163 | + * | |
| 164 | + * @param array the array | |
| 165 | + * @param index the index | |
| 166 | + * @return the value of the indexed component in the specified array | |
| 167 | + * @exception NullPointerException If the specified object is null | |
| 168 | + * @exception IllegalArgumentException If the specified object is not | |
| 169 | + * an array, or if the indexed element cannot be converted to the | |
| 170 | + * return type by an identity or widening conversion | |
| 171 | + * @exception ArrayIndexOutOfBoundsException If the specified {@code index} | |
| 172 | + * argument is negative, or if it is greater than or equal to the | |
| 173 | + * length of the specified array | |
| 174 | + * @see Array#get | |
| 175 | + */ | |
| 176 | + public static native byte getByte(Object array, int index) | |
| 177 | + throws IllegalArgumentException, ArrayIndexOutOfBoundsException; | |
| 178 | + | |
| 179 | + /** | |
| 180 | + * Returns the value of the indexed component in the specified | |
| 181 | + * array object, as a {@code char}. | |
| 182 | + * | |
| 183 | + * @param array the array | |
| 184 | + * @param index the index | |
| 185 | + * @return the value of the indexed component in the specified array | |
| 186 | + * @exception NullPointerException If the specified object is null | |
| 187 | + * @exception IllegalArgumentException If the specified object is not | |
| 188 | + * an array, or if the indexed element cannot be converted to the | |
| 189 | + * return type by an identity or widening conversion | |
| 190 | + * @exception ArrayIndexOutOfBoundsException If the specified {@code index} | |
| 191 | + * argument is negative, or if it is greater than or equal to the | |
| 192 | + * length of the specified array | |
| 193 | + * @see Array#get | |
| 194 | + */ | |
| 195 | + public static native char getChar(Object array, int index) | |
| 196 | + throws IllegalArgumentException, ArrayIndexOutOfBoundsException; | |
| 197 | + | |
| 198 | + /** | |
| 199 | + * Returns the value of the indexed component in the specified | |
| 200 | + * array object, as a {@code short}. | |
| 201 | + * | |
| 202 | + * @param array the array | |
| 203 | + * @param index the index | |
| 204 | + * @return the value of the indexed component in the specified array | |
| 205 | + * @exception NullPointerException If the specified object is null | |
| 206 | + * @exception IllegalArgumentException If the specified object is not | |
| 207 | + * an array, or if the indexed element cannot be converted to the | |
| 208 | + * return type by an identity or widening conversion | |
| 209 | + * @exception ArrayIndexOutOfBoundsException If the specified {@code index} | |
| 210 | + * argument is negative, or if it is greater than or equal to the | |
| 211 | + * length of the specified array | |
| 212 | + * @see Array#get | |
| 213 | + */ | |
| 214 | + public static native short getShort(Object array, int index) | |
| 215 | + throws IllegalArgumentException, ArrayIndexOutOfBoundsException; | |
| 216 | + | |
| 217 | + /** | |
| 218 | + * Returns the value of the indexed component in the specified | |
| 219 | + * array object, as an {@code int}. | |
| 220 | + * | |
| 221 | + * @param array the array | |
| 222 | + * @param index the index | |
| 223 | + * @return the value of the indexed component in the specified array | |
| 224 | + * @exception NullPointerException If the specified object is null | |
| 225 | + * @exception IllegalArgumentException If the specified object is not | |
| 226 | + * an array, or if the indexed element cannot be converted to the | |
| 227 | + * return type by an identity or widening conversion | |
| 228 | + * @exception ArrayIndexOutOfBoundsException If the specified {@code index} | |
| 229 | + * argument is negative, or if it is greater than or equal to the | |
| 230 | + * length of the specified array | |
| 231 | + * @see Array#get | |
| 232 | + */ | |
| 233 | + public static native int getInt(Object array, int index) | |
| 234 | + throws IllegalArgumentException, ArrayIndexOutOfBoundsException; | |
| 235 | + | |
| 236 | + /** | |
| 237 | + * Returns the value of the indexed component in the specified | |
| 238 | + * array object, as a {@code long}. | |
| 239 | + * | |
| 240 | + * @param array the array | |
| 241 | + * @param index the index | |
| 242 | + * @return the value of the indexed component in the specified array | |
| 243 | + * @exception NullPointerException If the specified object is null | |
| 244 | + * @exception IllegalArgumentException If the specified object is not | |
| 245 | + * an array, or if the indexed element cannot be converted to the | |
| 246 | + * return type by an identity or widening conversion | |
| 247 | + * @exception ArrayIndexOutOfBoundsException If the specified {@code index} | |
| 248 | + * argument is negative, or if it is greater than or equal to the | |
| 249 | + * length of the specified array | |
| 250 | + * @see Array#get | |
| 251 | + */ | |
| 252 | + public static native long getLong(Object array, int index) | |
| 253 | + throws IllegalArgumentException, ArrayIndexOutOfBoundsException; | |
| 254 | + | |
| 255 | + /** | |
| 256 | + * Returns the value of the indexed component in the specified | |
| 257 | + * array object, as a {@code float}. | |
| 258 | + * | |
| 259 | + * @param array the array | |
| 260 | + * @param index the index | |
| 261 | + * @return the value of the indexed component in the specified array | |
| 262 | + * @exception NullPointerException If the specified object is null | |
| 263 | + * @exception IllegalArgumentException If the specified object is not | |
| 264 | + * an array, or if the indexed element cannot be converted to the | |
| 265 | + * return type by an identity or widening conversion | |
| 266 | + * @exception ArrayIndexOutOfBoundsException If the specified {@code index} | |
| 267 | + * argument is negative, or if it is greater than or equal to the | |
| 268 | + * length of the specified array | |
| 269 | + * @see Array#get | |
| 270 | + */ | |
| 271 | + public static native float getFloat(Object array, int index) | |
| 272 | + throws IllegalArgumentException, ArrayIndexOutOfBoundsException; | |
| 273 | + | |
| 274 | + /** | |
| 275 | + * Returns the value of the indexed component in the specified | |
| 276 | + * array object, as a {@code double}. | |
| 277 | + * | |
| 278 | + * @param array the array | |
| 279 | + * @param index the index | |
| 280 | + * @return the value of the indexed component in the specified array | |
| 281 | + * @exception NullPointerException If the specified object is null | |
| 282 | + * @exception IllegalArgumentException If the specified object is not | |
| 283 | + * an array, or if the indexed element cannot be converted to the | |
| 284 | + * return type by an identity or widening conversion | |
| 285 | + * @exception ArrayIndexOutOfBoundsException If the specified {@code index} | |
| 286 | + * argument is negative, or if it is greater than or equal to the | |
| 287 | + * length of the specified array | |
| 288 | + * @see Array#get | |
| 289 | + */ | |
| 290 | + public static native double getDouble(Object array, int index) | |
| 291 | + throws IllegalArgumentException, ArrayIndexOutOfBoundsException; | |
| 292 | + | |
| 293 | + /** | |
| 294 | + * Sets the value of the indexed component of the specified array | |
| 295 | + * object to the specified new value. The new value is first | |
| 296 | + * automatically unwrapped if the array has a primitive component | |
| 297 | + * type. | |
| 298 | + * @param array the array | |
| 299 | + * @param index the index into the array | |
| 300 | + * @param value the new value of the indexed component | |
| 301 | + * @exception NullPointerException If the specified object argument | |
| 302 | + * is null | |
| 303 | + * @exception IllegalArgumentException If the specified object argument | |
| 304 | + * is not an array, or if the array component type is primitive and | |
| 305 | + * an unwrapping conversion fails | |
| 306 | + * @exception ArrayIndexOutOfBoundsException If the specified {@code index} | |
| 307 | + * argument is negative, or if it is greater than or equal to | |
| 308 | + * the length of the specified array | |
| 309 | + */ | |
| 310 | + public static native void set(Object array, int index, Object value) | |
| 311 | + throws IllegalArgumentException, ArrayIndexOutOfBoundsException; | |
| 312 | + | |
| 313 | + /** | |
| 314 | + * Sets the value of the indexed component of the specified array | |
| 315 | + * object to the specified {@code boolean} value. | |
| 316 | + * @param array the array | |
| 317 | + * @param index the index into the array | |
| 318 | + * @param z the new value of the indexed component | |
| 319 | + * @exception NullPointerException If the specified object argument | |
| 320 | + * is null | |
| 321 | + * @exception IllegalArgumentException If the specified object argument | |
| 322 | + * is not an array, or if the specified value cannot be converted | |
| 323 | + * to the underlying array's component type by an identity or a | |
| 324 | + * primitive widening conversion | |
| 325 | + * @exception ArrayIndexOutOfBoundsException If the specified {@code index} | |
| 326 | + * argument is negative, or if it is greater than or equal to | |
| 327 | + * the length of the specified array | |
| 328 | + * @see Array#set | |
| 329 | + */ | |
| 330 | + public static native void setBoolean(Object array, int index, boolean z) | |
| 331 | + throws IllegalArgumentException, ArrayIndexOutOfBoundsException; | |
| 332 | + | |
| 333 | + /** | |
| 334 | + * Sets the value of the indexed component of the specified array | |
| 335 | + * object to the specified {@code byte} value. | |
| 336 | + * @param array the array | |
| 337 | + * @param index the index into the array | |
| 338 | + * @param b the new value of the indexed component | |
| 339 | + * @exception NullPointerException If the specified object argument | |
| 340 | + * is null | |
| 341 | + * @exception IllegalArgumentException If the specified object argument | |
| 342 | + * is not an array, or if the specified value cannot be converted | |
| 343 | + * to the underlying array's component type by an identity or a | |
| 344 | + * primitive widening conversion | |
| 345 | + * @exception ArrayIndexOutOfBoundsException If the specified {@code index} | |
| 346 | + * argument is negative, or if it is greater than or equal to | |
| 347 | + * the length of the specified array | |
| 348 | + * @see Array#set | |
| 349 | + */ | |
| 350 | + public static native void setByte(Object array, int index, byte b) | |
| 351 | + throws IllegalArgumentException, ArrayIndexOutOfBoundsException; | |
| 352 | + | |
| 353 | + /** | |
| 354 | + * Sets the value of the indexed component of the specified array | |
| 355 | + * object to the specified {@code char} value. | |
| 356 | + * @param array the array | |
| 357 | + * @param index the index into the array | |
| 358 | + * @param c the new value of the indexed component | |
| 359 | + * @exception NullPointerException If the specified object argument | |
| 360 | + * is null | |
| 361 | + * @exception IllegalArgumentException If the specified object argument | |
| 362 | + * is not an array, or if the specified value cannot be converted | |
| 363 | + * to the underlying array's component type by an identity or a | |
| 364 | + * primitive widening conversion | |
| 365 | + * @exception ArrayIndexOutOfBoundsException If the specified {@code index} | |
| 366 | + * argument is negative, or if it is greater than or equal to | |
| 367 | + * the length of the specified array | |
| 368 | + * @see Array#set | |
| 369 | + */ | |
| 370 | + public static native void setChar(Object array, int index, char c) | |
| 371 | + throws IllegalArgumentException, ArrayIndexOutOfBoundsException; | |
| 372 | + | |
| 373 | + /** | |
| 374 | + * Sets the value of the indexed component of the specified array | |
| 375 | + * object to the specified {@code short} value. | |
| 376 | + * @param array the array | |
| 377 | + * @param index the index into the array | |
| 378 | + * @param s the new value of the indexed component | |
| 379 | + * @exception NullPointerException If the specified object argument | |
| 380 | + * is null | |
| 381 | + * @exception IllegalArgumentException If the specified object argument | |
| 382 | + * is not an array, or if the specified value cannot be converted | |
| 383 | + * to the underlying array's component type by an identity or a | |
| 384 | + * primitive widening conversion | |
| 385 | + * @exception ArrayIndexOutOfBoundsException If the specified {@code index} | |
| 386 | + * argument is negative, or if it is greater than or equal to | |
| 387 | + * the length of the specified array | |
| 388 | + * @see Array#set | |
| 389 | + */ | |
| 390 | + public static native void setShort(Object array, int index, short s) | |
| 391 | + throws IllegalArgumentException, ArrayIndexOutOfBoundsException; | |
| 392 | + | |
| 393 | + /** | |
| 394 | + * Sets the value of the indexed component of the specified array | |
| 395 | + * object to the specified {@code int} value. | |
| 396 | + * @param array the array | |
| 397 | + * @param index the index into the array | |
| 398 | + * @param i the new value of the indexed component | |
| 399 | + * @exception NullPointerException If the specified object argument | |
| 400 | + * is null | |
| 401 | + * @exception IllegalArgumentException If the specified object argument | |
| 402 | + * is not an array, or if the specified value cannot be converted | |
| 403 | + * to the underlying array's component type by an identity or a | |
| 404 | + * primitive widening conversion | |
| 405 | + * @exception ArrayIndexOutOfBoundsException If the specified {@code index} | |
| 406 | + * argument is negative, or if it is greater than or equal to | |
| 407 | + * the length of the specified array | |
| 408 | + * @see Array#set | |
| 409 | + */ | |
| 410 | + public static native void setInt(Object array, int index, int i) | |
| 411 | + throws IllegalArgumentException, ArrayIndexOutOfBoundsException; | |
| 412 | + | |
| 413 | + /** | |
| 414 | + * Sets the value of the indexed component of the specified array | |
| 415 | + * object to the specified {@code long} value. | |
| 416 | + * @param array the array | |
| 417 | + * @param index the index into the array | |
| 418 | + * @param l the new value of the indexed component | |
| 419 | + * @exception NullPointerException If the specified object argument | |
| 420 | + * is null | |
| 421 | + * @exception IllegalArgumentException If the specified object argument | |
| 422 | + * is not an array, or if the specified value cannot be converted | |
| 423 | + * to the underlying array's component type by an identity or a | |
| 424 | + * primitive widening conversion | |
| 425 | + * @exception ArrayIndexOutOfBoundsException If the specified {@code index} | |
| 426 | + * argument is negative, or if it is greater than or equal to | |
| 427 | + * the length of the specified array | |
| 428 | + * @see Array#set | |
| 429 | + */ | |
| 430 | + public static native void setLong(Object array, int index, long l) | |
| 431 | + throws IllegalArgumentException, ArrayIndexOutOfBoundsException; | |
| 432 | + | |
| 433 | + /** | |
| 434 | + * Sets the value of the indexed component of the specified array | |
| 435 | + * object to the specified {@code float} value. | |
| 436 | + * @param array the array | |
| 437 | + * @param index the index into the array | |
| 438 | + * @param f the new value of the indexed component | |
| 439 | + * @exception NullPointerException If the specified object argument | |
| 440 | + * is null | |
| 441 | + * @exception IllegalArgumentException If the specified object argument | |
| 442 | + * is not an array, or if the specified value cannot be converted | |
| 443 | + * to the underlying array's component type by an identity or a | |
| 444 | + * primitive widening conversion | |
| 445 | + * @exception ArrayIndexOutOfBoundsException If the specified {@code index} | |
| 446 | + * argument is negative, or if it is greater than or equal to | |
| 447 | + * the length of the specified array | |
| 448 | + * @see Array#set | |
| 449 | + */ | |
| 450 | + public static native void setFloat(Object array, int index, float f) | |
| 451 | + throws IllegalArgumentException, ArrayIndexOutOfBoundsException; | |
| 452 | + | |
| 453 | + /** | |
| 454 | + * Sets the value of the indexed component of the specified array | |
| 455 | + * object to the specified {@code double} value. | |
| 456 | + * @param array the array | |
| 457 | + * @param index the index into the array | |
| 458 | + * @param d the new value of the indexed component | |
| 459 | + * @exception NullPointerException If the specified object argument | |
| 460 | + * is null | |
| 461 | + * @exception IllegalArgumentException If the specified object argument | |
| 462 | + * is not an array, or if the specified value cannot be converted | |
| 463 | + * to the underlying array's component type by an identity or a | |
| 464 | + * primitive widening conversion | |
| 465 | + * @exception ArrayIndexOutOfBoundsException If the specified {@code index} | |
| 466 | + * argument is negative, or if it is greater than or equal to | |
| 467 | + * the length of the specified array | |
| 468 | + * @see Array#set | |
| 469 | + */ | |
| 470 | + public static native void setDouble(Object array, int index, double d) | |
| 471 | + throws IllegalArgumentException, ArrayIndexOutOfBoundsException; | |
| 472 | + | |
| 473 | + /* | |
| 474 | + * Private | |
| 475 | + */ | |
| 476 | + | |
| 477 | + private static native Object newArray(Class componentType, int length) | |
| 478 | + throws NegativeArraySizeException; | |
| 479 | + | |
| 480 | + private static native Object multiNewArray(Class componentType, | |
| 481 | + int[] dimensions) | |
| 482 | + throws IllegalArgumentException, NegativeArraySizeException; | |
| 483 | + | |
| 484 | + | |
| 485 | +} | |
Binary file not shown.
| @@ -0,0 +1,683 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.lang.reflect; | |
| 27 | + | |
| 28 | +import sun.reflect.ConstructorAccessor; | |
| 29 | +import sun.reflect.Reflection; | |
| 30 | +import sun.reflect.generics.repository.ConstructorRepository; | |
| 31 | +import sun.reflect.generics.factory.CoreReflectionFactory; | |
| 32 | +import sun.reflect.generics.factory.GenericsFactory; | |
| 33 | +import sun.reflect.generics.scope.ConstructorScope; | |
| 34 | +import java.lang.annotation.Annotation; | |
| 35 | +import java.util.Map; | |
| 36 | +import sun.reflect.annotation.AnnotationParser; | |
| 37 | +import java.lang.annotation.AnnotationFormatError; | |
| 38 | +import java.lang.reflect.Modifier; | |
| 39 | + | |
| 40 | +/** | |
| 41 | + * {@code Constructor} provides information about, and access to, a single | |
| 42 | + * constructor for a class. | |
| 43 | + * | |
| 44 | + * <p>{@code Constructor} permits widening conversions to occur when matching the | |
| 45 | + * actual parameters to newInstance() with the underlying | |
| 46 | + * constructor's formal parameters, but throws an | |
| 47 | + * {@code IllegalArgumentException} if a narrowing conversion would occur. | |
| 48 | + * | |
| 49 | + * @param <T> the class in which the constructor is declared | |
| 50 | + * | |
| 51 | + * @see Member | |
| 52 | + * @see java.lang.Class | |
| 53 | + * @see java.lang.Class#getConstructors() | |
| 54 | + * @see java.lang.Class#getConstructor(Class[]) | |
| 55 | + * @see java.lang.Class#getDeclaredConstructors() | |
| 56 | + * | |
| 57 | + * @author Kenneth Russell | |
| 58 | + * @author Nakul Saraiya | |
| 59 | + */ | |
| 60 | +public final | |
| 61 | + class Constructor<T> extends AccessibleObject implements | |
| 62 | + GenericDeclaration, | |
| 63 | + Member { | |
| 64 | + | |
| 65 | + private Class<T> clazz; | |
| 66 | + private int slot; | |
| 67 | + private Class<?>[] parameterTypes; | |
| 68 | + private Class<?>[] exceptionTypes; | |
| 69 | + private int modifiers; | |
| 70 | + // Generics and annotations support | |
| 71 | + private transient String signature; | |
| 72 | + // generic info repository; lazily initialized | |
| 73 | + private transient ConstructorRepository genericInfo; | |
| 74 | + private byte[] annotations; | |
| 75 | + private byte[] parameterAnnotations; | |
| 76 | + | |
| 77 | + // Generics infrastructure | |
| 78 | + // Accessor for factory | |
| 79 | + private GenericsFactory getFactory() { | |
| 80 | + // create scope and factory | |
| 81 | + return CoreReflectionFactory.make(this, ConstructorScope.make(this)); | |
| 82 | + } | |
| 83 | + | |
| 84 | + // Accessor for generic info repository | |
| 85 | + private ConstructorRepository getGenericInfo() { | |
| 86 | + // lazily initialize repository if necessary | |
| 87 | + if (genericInfo == null) { | |
| 88 | + // create and cache generic info repository | |
| 89 | + genericInfo = | |
| 90 | + ConstructorRepository.make(getSignature(), | |
| 91 | + getFactory()); | |
| 92 | + } | |
| 93 | + return genericInfo; //return cached repository | |
| 94 | + } | |
| 95 | + | |
| 96 | + private volatile ConstructorAccessor constructorAccessor; | |
| 97 | + // For sharing of ConstructorAccessors. This branching structure | |
| 98 | + // is currently only two levels deep (i.e., one root Constructor | |
| 99 | + // and potentially many Constructor objects pointing to it.) | |
| 100 | + private Constructor<T> root; | |
| 101 | + | |
| 102 | + /** | |
| 103 | + * Package-private constructor used by ReflectAccess to enable | |
| 104 | + * instantiation of these objects in Java code from the java.lang | |
| 105 | + * package via sun.reflect.LangReflectAccess. | |
| 106 | + */ | |
| 107 | + Constructor(Class<T> declaringClass, | |
| 108 | + Class<?>[] parameterTypes, | |
| 109 | + Class<?>[] checkedExceptions, | |
| 110 | + int modifiers, | |
| 111 | + int slot, | |
| 112 | + String signature, | |
| 113 | + byte[] annotations, | |
| 114 | + byte[] parameterAnnotations) | |
| 115 | + { | |
| 116 | + this.clazz = declaringClass; | |
| 117 | + this.parameterTypes = parameterTypes; | |
| 118 | + this.exceptionTypes = checkedExceptions; | |
| 119 | + this.modifiers = modifiers; | |
| 120 | + this.slot = slot; | |
| 121 | + this.signature = signature; | |
| 122 | + this.annotations = annotations; | |
| 123 | + this.parameterAnnotations = parameterAnnotations; | |
| 124 | + } | |
| 125 | + | |
| 126 | + /** | |
| 127 | + * Package-private routine (exposed to java.lang.Class via | |
| 128 | + * ReflectAccess) which returns a copy of this Constructor. The copy's | |
| 129 | + * "root" field points to this Constructor. | |
| 130 | + */ | |
| 131 | + Constructor<T> copy() { | |
| 132 | + // This routine enables sharing of ConstructorAccessor objects | |
| 133 | + // among Constructor objects which refer to the same underlying | |
| 134 | + // method in the VM. (All of this contortion is only necessary | |
| 135 | + // because of the "accessibility" bit in AccessibleObject, | |
| 136 | + // which implicitly requires that new java.lang.reflect | |
| 137 | + // objects be fabricated for each reflective call on Class | |
| 138 | + // objects.) | |
| 139 | + Constructor<T> res = new Constructor<>(clazz, | |
| 140 | + parameterTypes, | |
| 141 | + exceptionTypes, modifiers, slot, | |
| 142 | + signature, | |
| 143 | + annotations, | |
| 144 | + parameterAnnotations); | |
| 145 | + res.root = this; | |
| 146 | + // Might as well eagerly propagate this if already present | |
| 147 | + res.constructorAccessor = constructorAccessor; | |
| 148 | + return res; | |
| 149 | + } | |
| 150 | + | |
| 151 | + /** | |
| 152 | + * Returns the {@code Class} object representing the class that declares | |
| 153 | + * the constructor represented by this {@code Constructor} object. | |
| 154 | + */ | |
| 155 | + public Class<T> getDeclaringClass() { | |
| 156 | + return clazz; | |
| 157 | + } | |
| 158 | + | |
| 159 | + /** | |
| 160 | + * Returns the name of this constructor, as a string. This is | |
| 161 | + * the binary name of the constructor's declaring class. | |
| 162 | + */ | |
| 163 | + public String getName() { | |
| 164 | + return getDeclaringClass().getName(); | |
| 165 | + } | |
| 166 | + | |
| 167 | + /** | |
| 168 | + * Returns the Java language modifiers for the constructor | |
| 169 | + * represented by this {@code Constructor} object, as an integer. The | |
| 170 | + * {@code Modifier} class should be used to decode the modifiers. | |
| 171 | + * | |
| 172 | + * @see Modifier | |
| 173 | + */ | |
| 174 | + public int getModifiers() { | |
| 175 | + return modifiers; | |
| 176 | + } | |
| 177 | + | |
| 178 | + /** | |
| 179 | + * Returns an array of {@code TypeVariable} objects that represent the | |
| 180 | + * type variables declared by the generic declaration represented by this | |
| 181 | + * {@code GenericDeclaration} object, in declaration order. Returns an | |
| 182 | + * array of length 0 if the underlying generic declaration declares no type | |
| 183 | + * variables. | |
| 184 | + * | |
| 185 | + * @return an array of {@code TypeVariable} objects that represent | |
| 186 | + * the type variables declared by this generic declaration | |
| 187 | + * @throws GenericSignatureFormatError if the generic | |
| 188 | + * signature of this generic declaration does not conform to | |
| 189 | + * the format specified in | |
| 190 | + * <cite>The Java™ Virtual Machine Specification</cite> | |
| 191 | + * @since 1.5 | |
| 192 | + */ | |
| 193 | + public TypeVariable<Constructor<T>>[] getTypeParameters() { | |
| 194 | + if (getSignature() != null) { | |
| 195 | + return (TypeVariable<Constructor<T>>[])getGenericInfo().getTypeParameters(); | |
| 196 | + } else | |
| 197 | + return (TypeVariable<Constructor<T>>[])new TypeVariable[0]; | |
| 198 | + } | |
| 199 | + | |
| 200 | + | |
| 201 | + /** | |
| 202 | + * Returns an array of {@code Class} objects that represent the formal | |
| 203 | + * parameter types, in declaration order, of the constructor | |
| 204 | + * represented by this {@code Constructor} object. Returns an array of | |
| 205 | + * length 0 if the underlying constructor takes no parameters. | |
| 206 | + * | |
| 207 | + * @return the parameter types for the constructor this object | |
| 208 | + * represents | |
| 209 | + */ | |
| 210 | + public Class<?>[] getParameterTypes() { | |
| 211 | + return (Class<?>[]) parameterTypes.clone(); | |
| 212 | + } | |
| 213 | + | |
| 214 | + | |
| 215 | + /** | |
| 216 | + * Returns an array of {@code Type} objects that represent the formal | |
| 217 | + * parameter types, in declaration order, of the method represented by | |
| 218 | + * this {@code Constructor} object. Returns an array of length 0 if the | |
| 219 | + * underlying method takes no parameters. | |
| 220 | + * | |
| 221 | + * <p>If a formal parameter type is a parameterized type, | |
| 222 | + * the {@code Type} object returned for it must accurately reflect | |
| 223 | + * the actual type parameters used in the source code. | |
| 224 | + * | |
| 225 | + * <p>If a formal parameter type is a type variable or a parameterized | |
| 226 | + * type, it is created. Otherwise, it is resolved. | |
| 227 | + * | |
| 228 | + * @return an array of {@code Type}s that represent the formal | |
| 229 | + * parameter types of the underlying method, in declaration order | |
| 230 | + * @throws GenericSignatureFormatError | |
| 231 | + * if the generic method signature does not conform to the format | |
| 232 | + * specified in | |
| 233 | + * <cite>The Java™ Virtual Machine Specification</cite> | |
| 234 | + * @throws TypeNotPresentException if any of the parameter | |
| 235 | + * types of the underlying method refers to a non-existent type | |
| 236 | + * declaration | |
| 237 | + * @throws MalformedParameterizedTypeException if any of | |
| 238 | + * the underlying method's parameter types refer to a parameterized | |
| 239 | + * type that cannot be instantiated for any reason | |
| 240 | + * @since 1.5 | |
| 241 | + */ | |
| 242 | + public Type[] getGenericParameterTypes() { | |
| 243 | + if (getSignature() != null) | |
| 244 | + return getGenericInfo().getParameterTypes(); | |
| 245 | + else | |
| 246 | + return getParameterTypes(); | |
| 247 | + } | |
| 248 | + | |
| 249 | + | |
| 250 | + /** | |
| 251 | + * Returns an array of {@code Class} objects that represent the types | |
| 252 | + * of exceptions declared to be thrown by the underlying constructor | |
| 253 | + * represented by this {@code Constructor} object. Returns an array of | |
| 254 | + * length 0 if the constructor declares no exceptions in its {@code throws} clause. | |
| 255 | + * | |
| 256 | + * @return the exception types declared as being thrown by the | |
| 257 | + * constructor this object represents | |
| 258 | + */ | |
| 259 | + public Class<?>[] getExceptionTypes() { | |
| 260 | + return (Class<?>[])exceptionTypes.clone(); | |
| 261 | + } | |
| 262 | + | |
| 263 | + | |
| 264 | + /** | |
| 265 | + * Returns an array of {@code Type} objects that represent the | |
| 266 | + * exceptions declared to be thrown by this {@code Constructor} object. | |
| 267 | + * Returns an array of length 0 if the underlying method declares | |
| 268 | + * no exceptions in its {@code throws} clause. | |
| 269 | + * | |
| 270 | + * <p>If an exception type is a type variable or a parameterized | |
| 271 | + * type, it is created. Otherwise, it is resolved. | |
| 272 | + * | |
| 273 | + * @return an array of Types that represent the exception types | |
| 274 | + * thrown by the underlying method | |
| 275 | + * @throws GenericSignatureFormatError | |
| 276 | + * if the generic method signature does not conform to the format | |
| 277 | + * specified in | |
| 278 | + * <cite>The Java™ Virtual Machine Specification</cite> | |
| 279 | + * @throws TypeNotPresentException if the underlying method's | |
| 280 | + * {@code throws} clause refers to a non-existent type declaration | |
| 281 | + * @throws MalformedParameterizedTypeException if | |
| 282 | + * the underlying method's {@code throws} clause refers to a | |
| 283 | + * parameterized type that cannot be instantiated for any reason | |
| 284 | + * @since 1.5 | |
| 285 | + */ | |
| 286 | + public Type[] getGenericExceptionTypes() { | |
| 287 | + Type[] result; | |
| 288 | + if (getSignature() != null && | |
| 289 | + ( (result = getGenericInfo().getExceptionTypes()).length > 0 )) | |
| 290 | + return result; | |
| 291 | + else | |
| 292 | + return getExceptionTypes(); | |
| 293 | + } | |
| 294 | + | |
| 295 | + /** | |
| 296 | + * Compares this {@code Constructor} against the specified object. | |
| 297 | + * Returns true if the objects are the same. Two {@code Constructor} objects are | |
| 298 | + * the same if they were declared by the same class and have the | |
| 299 | + * same formal parameter types. | |
| 300 | + */ | |
| 301 | + public boolean equals(Object obj) { | |
| 302 | + if (obj != null && obj instanceof Constructor) { | |
| 303 | + Constructor<?> other = (Constructor<?>)obj; | |
| 304 | + if (getDeclaringClass() == other.getDeclaringClass()) { | |
| 305 | + /* Avoid unnecessary cloning */ | |
| 306 | + Class<?>[] params1 = parameterTypes; | |
| 307 | + Class<?>[] params2 = other.parameterTypes; | |
| 308 | + if (params1.length == params2.length) { | |
| 309 | + for (int i = 0; i < params1.length; i++) { | |
| 310 | + if (params1[i] != params2[i]) | |
| 311 | + return false; | |
| 312 | + } | |
| 313 | + return true; | |
| 314 | + } | |
| 315 | + } | |
| 316 | + } | |
| 317 | + return false; | |
| 318 | + } | |
| 319 | + | |
| 320 | + /** | |
| 321 | + * Returns a hashcode for this {@code Constructor}. The hashcode is | |
| 322 | + * the same as the hashcode for the underlying constructor's | |
| 323 | + * declaring class name. | |
| 324 | + */ | |
| 325 | + public int hashCode() { | |
| 326 | + return getDeclaringClass().getName().hashCode(); | |
| 327 | + } | |
| 328 | + | |
| 329 | + /** | |
| 330 | + * Returns a string describing this {@code Constructor}. The string is | |
| 331 | + * formatted as the constructor access modifiers, if any, | |
| 332 | + * followed by the fully-qualified name of the declaring class, | |
| 333 | + * followed by a parenthesized, comma-separated list of the | |
| 334 | + * constructor's formal parameter types. For example: | |
| 335 | + * <pre> | |
| 336 | + * public java.util.Hashtable(int,float) | |
| 337 | + * </pre> | |
| 338 | + * | |
| 339 | + * <p>The only possible modifiers for constructors are the access | |
| 340 | + * modifiers {@code public}, {@code protected} or | |
| 341 | + * {@code private}. Only one of these may appear, or none if the | |
| 342 | + * constructor has default (package) access. | |
| 343 | + */ | |
| 344 | + public String toString() { | |
| 345 | + try { | |
| 346 | + StringBuffer sb = new StringBuffer(); | |
| 347 | + int mod = getModifiers() & Modifier.constructorModifiers(); | |
| 348 | + if (mod != 0) { | |
| 349 | + sb.append(Modifier.toString(mod) + " "); | |
| 350 | + } | |
| 351 | + sb.append(Field.getTypeName(getDeclaringClass())); | |
| 352 | + sb.append("("); | |
| 353 | + Class<?>[] params = parameterTypes; // avoid clone | |
| 354 | + for (int j = 0; j < params.length; j++) { | |
| 355 | + sb.append(Field.getTypeName(params[j])); | |
| 356 | + if (j < (params.length - 1)) | |
| 357 | + sb.append(","); | |
| 358 | + } | |
| 359 | + sb.append(")"); | |
| 360 | + Class<?>[] exceptions = exceptionTypes; // avoid clone | |
| 361 | + if (exceptions.length > 0) { | |
| 362 | + sb.append(" throws "); | |
| 363 | + for (int k = 0; k < exceptions.length; k++) { | |
| 364 | + sb.append(exceptions[k].getName()); | |
| 365 | + if (k < (exceptions.length - 1)) | |
| 366 | + sb.append(","); | |
| 367 | + } | |
| 368 | + } | |
| 369 | + return sb.toString(); | |
| 370 | + } catch (Exception e) { | |
| 371 | + return "<" + e + ">"; | |
| 372 | + } | |
| 373 | + } | |
| 374 | + | |
| 375 | + /** | |
| 376 | + * Returns a string describing this {@code Constructor}, | |
| 377 | + * including type parameters. The string is formatted as the | |
| 378 | + * constructor access modifiers, if any, followed by an | |
| 379 | + * angle-bracketed comma separated list of the constructor's type | |
| 380 | + * parameters, if any, followed by the fully-qualified name of the | |
| 381 | + * declaring class, followed by a parenthesized, comma-separated | |
| 382 | + * list of the constructor's generic formal parameter types. | |
| 383 | + * | |
| 384 | + * If this constructor was declared to take a variable number of | |
| 385 | + * arguments, instead of denoting the last parameter as | |
| 386 | + * "<tt><i>Type</i>[]</tt>", it is denoted as | |
| 387 | + * "<tt><i>Type</i>...</tt>". | |
| 388 | + * | |
| 389 | + * A space is used to separate access modifiers from one another | |
| 390 | + * and from the type parameters or return type. If there are no | |
| 391 | + * type parameters, the type parameter list is elided; if the type | |
| 392 | + * parameter list is present, a space separates the list from the | |
| 393 | + * class name. If the constructor is declared to throw | |
| 394 | + * exceptions, the parameter list is followed by a space, followed | |
| 395 | + * by the word "{@code throws}" followed by a | |
| 396 | + * comma-separated list of the thrown exception types. | |
| 397 | + * | |
| 398 | + * <p>The only possible modifiers for constructors are the access | |
| 399 | + * modifiers {@code public}, {@code protected} or | |
| 400 | + * {@code private}. Only one of these may appear, or none if the | |
| 401 | + * constructor has default (package) access. | |
| 402 | + * | |
| 403 | + * @return a string describing this {@code Constructor}, | |
| 404 | + * include type parameters | |
| 405 | + * | |
| 406 | + * @since 1.5 | |
| 407 | + */ | |
| 408 | + public String toGenericString() { | |
| 409 | + try { | |
| 410 | + StringBuilder sb = new StringBuilder(); | |
| 411 | + int mod = getModifiers() & Modifier.constructorModifiers(); | |
| 412 | + if (mod != 0) { | |
| 413 | + sb.append(Modifier.toString(mod) + " "); | |
| 414 | + } | |
| 415 | + TypeVariable<?>[] typeparms = getTypeParameters(); | |
| 416 | + if (typeparms.length > 0) { | |
| 417 | + boolean first = true; | |
| 418 | + sb.append("<"); | |
| 419 | + for(TypeVariable<?> typeparm: typeparms) { | |
| 420 | + if (!first) | |
| 421 | + sb.append(","); | |
| 422 | + // Class objects can't occur here; no need to test | |
| 423 | + // and call Class.getName(). | |
| 424 | + sb.append(typeparm.toString()); | |
| 425 | + first = false; | |
| 426 | + } | |
| 427 | + sb.append("> "); | |
| 428 | + } | |
| 429 | + sb.append(Field.getTypeName(getDeclaringClass())); | |
| 430 | + sb.append("("); | |
| 431 | + Type[] params = getGenericParameterTypes(); | |
| 432 | + for (int j = 0; j < params.length; j++) { | |
| 433 | + String param = (params[j] instanceof Class<?>)? | |
| 434 | + Field.getTypeName((Class<?>)params[j]): | |
| 435 | + (params[j].toString()); | |
| 436 | + if (isVarArgs() && (j == params.length - 1)) // replace T[] with T... | |
| 437 | + param = param.replaceFirst("\\[\\]$", "..."); | |
| 438 | + sb.append(param); | |
| 439 | + if (j < (params.length - 1)) | |
| 440 | + sb.append(","); | |
| 441 | + } | |
| 442 | + sb.append(")"); | |
| 443 | + Type[] exceptions = getGenericExceptionTypes(); | |
| 444 | + if (exceptions.length > 0) { | |
| 445 | + sb.append(" throws "); | |
| 446 | + for (int k = 0; k < exceptions.length; k++) { | |
| 447 | + sb.append((exceptions[k] instanceof Class)? | |
| 448 | + ((Class<?>)exceptions[k]).getName(): | |
| 449 | + exceptions[k].toString()); | |
| 450 | + if (k < (exceptions.length - 1)) | |
| 451 | + sb.append(","); | |
| 452 | + } | |
| 453 | + } | |
| 454 | + return sb.toString(); | |
| 455 | + } catch (Exception e) { | |
| 456 | + return "<" + e + ">"; | |
| 457 | + } | |
| 458 | + } | |
| 459 | + | |
| 460 | + /** | |
| 461 | + * Uses the constructor represented by this {@code Constructor} object to | |
| 462 | + * create and initialize a new instance of the constructor's | |
| 463 | + * declaring class, with the specified initialization parameters. | |
| 464 | + * Individual parameters are automatically unwrapped to match | |
| 465 | + * primitive formal parameters, and both primitive and reference | |
| 466 | + * parameters are subject to method invocation conversions as necessary. | |
| 467 | + * | |
| 468 | + * <p>If the number of formal parameters required by the underlying constructor | |
| 469 | + * is 0, the supplied {@code initargs} array may be of length 0 or null. | |
| 470 | + * | |
| 471 | + * <p>If the constructor's declaring class is an inner class in a | |
| 472 | + * non-static context, the first argument to the constructor needs | |
| 473 | + * to be the enclosing instance; see section 15.9.3 of | |
| 474 | + * <cite>The Java™ Language Specification</cite>. | |
| 475 | + * | |
| 476 | + * <p>If the required access and argument checks succeed and the | |
| 477 | + * instantiation will proceed, the constructor's declaring class | |
| 478 | + * is initialized if it has not already been initialized. | |
| 479 | + * | |
| 480 | + * <p>If the constructor completes normally, returns the newly | |
| 481 | + * created and initialized instance. | |
| 482 | + * | |
| 483 | + * @param initargs array of objects to be passed as arguments to | |
| 484 | + * the constructor call; values of primitive types are wrapped in | |
| 485 | + * a wrapper object of the appropriate type (e.g. a {@code float} | |
| 486 | + * in a {@link java.lang.Float Float}) | |
| 487 | + * | |
| 488 | + * @return a new object created by calling the constructor | |
| 489 | + * this object represents | |
| 490 | + * | |
| 491 | + * @exception IllegalAccessException if this {@code Constructor} object | |
| 492 | + * is enforcing Java language access control and the underlying | |
| 493 | + * constructor is inaccessible. | |
| 494 | + * @exception IllegalArgumentException if the number of actual | |
| 495 | + * and formal parameters differ; if an unwrapping | |
| 496 | + * conversion for primitive arguments fails; or if, | |
| 497 | + * after possible unwrapping, a parameter value | |
| 498 | + * cannot be converted to the corresponding formal | |
| 499 | + * parameter type by a method invocation conversion; if | |
| 500 | + * this constructor pertains to an enum type. | |
| 501 | + * @exception InstantiationException if the class that declares the | |
| 502 | + * underlying constructor represents an abstract class. | |
| 503 | + * @exception InvocationTargetException if the underlying constructor | |
| 504 | + * throws an exception. | |
| 505 | + * @exception ExceptionInInitializerError if the initialization provoked | |
| 506 | + * by this method fails. | |
| 507 | + */ | |
| 508 | + public T newInstance(Object ... initargs) | |
| 509 | + throws InstantiationException, IllegalAccessException, | |
| 510 | + IllegalArgumentException, InvocationTargetException | |
| 511 | + { | |
| 512 | + if (!override) { | |
| 513 | + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { | |
| 514 | + Class<?> caller = Reflection.getCallerClass(2); | |
| 515 | + | |
| 516 | + checkAccess(caller, clazz, null, modifiers); | |
| 517 | + } | |
| 518 | + } | |
| 519 | + if ((clazz.getModifiers() & Modifier.ENUM) != 0) | |
| 520 | + throw new IllegalArgumentException("Cannot reflectively create enum objects"); | |
| 521 | + ConstructorAccessor ca = constructorAccessor; // read volatile | |
| 522 | + if (ca == null) { | |
| 523 | + ca = acquireConstructorAccessor(); | |
| 524 | + } | |
| 525 | + return (T) ca.newInstance(initargs); | |
| 526 | + } | |
| 527 | + | |
| 528 | + /** | |
| 529 | + * Returns {@code true} if this constructor was declared to take | |
| 530 | + * a variable number of arguments; returns {@code false} | |
| 531 | + * otherwise. | |
| 532 | + * | |
| 533 | + * @return {@code true} if an only if this constructor was declared to | |
| 534 | + * take a variable number of arguments. | |
| 535 | + * @since 1.5 | |
| 536 | + */ | |
| 537 | + public boolean isVarArgs() { | |
| 538 | + return (getModifiers() & Modifier.VARARGS) != 0; | |
| 539 | + } | |
| 540 | + | |
| 541 | + /** | |
| 542 | + * Returns {@code true} if this constructor is a synthetic | |
| 543 | + * constructor; returns {@code false} otherwise. | |
| 544 | + * | |
| 545 | + * @return true if and only if this constructor is a synthetic | |
| 546 | + * constructor as defined by | |
| 547 | + * <cite>The Java™ Language Specification</cite>. | |
| 548 | + * @since 1.5 | |
| 549 | + */ | |
| 550 | + public boolean isSynthetic() { | |
| 551 | + return Modifier.isSynthetic(getModifiers()); | |
| 552 | + } | |
| 553 | + | |
| 554 | + // NOTE that there is no synchronization used here. It is correct | |
| 555 | + // (though not efficient) to generate more than one | |
| 556 | + // ConstructorAccessor for a given Constructor. However, avoiding | |
| 557 | + // synchronization will probably make the implementation more | |
| 558 | + // scalable. | |
| 559 | + private ConstructorAccessor acquireConstructorAccessor() { | |
| 560 | + // First check to see if one has been created yet, and take it | |
| 561 | + // if so. | |
| 562 | + ConstructorAccessor tmp = null; | |
| 563 | + if (root != null) tmp = root.getConstructorAccessor(); | |
| 564 | + if (tmp != null) { | |
| 565 | + constructorAccessor = tmp; | |
| 566 | + } else { | |
| 567 | + // Otherwise fabricate one and propagate it up to the root | |
| 568 | + tmp = reflectionFactory.newConstructorAccessor(this); | |
| 569 | + setConstructorAccessor(tmp); | |
| 570 | + } | |
| 571 | + | |
| 572 | + return tmp; | |
| 573 | + } | |
| 574 | + | |
| 575 | + // Returns ConstructorAccessor for this Constructor object, not | |
| 576 | + // looking up the chain to the root | |
| 577 | + ConstructorAccessor getConstructorAccessor() { | |
| 578 | + return constructorAccessor; | |
| 579 | + } | |
| 580 | + | |
| 581 | + // Sets the ConstructorAccessor for this Constructor object and | |
| 582 | + // (recursively) its root | |
| 583 | + void setConstructorAccessor(ConstructorAccessor accessor) { | |
| 584 | + constructorAccessor = accessor; | |
| 585 | + // Propagate up | |
| 586 | + if (root != null) { | |
| 587 | + root.setConstructorAccessor(accessor); | |
| 588 | + } | |
| 589 | + } | |
| 590 | + | |
| 591 | + int getSlot() { | |
| 592 | + return slot; | |
| 593 | + } | |
| 594 | + | |
| 595 | + String getSignature() { | |
| 596 | + return signature; | |
| 597 | + } | |
| 598 | + | |
| 599 | + byte[] getRawAnnotations() { | |
| 600 | + return annotations; | |
| 601 | + } | |
| 602 | + | |
| 603 | + byte[] getRawParameterAnnotations() { | |
| 604 | + return parameterAnnotations; | |
| 605 | + } | |
| 606 | + | |
| 607 | + /** | |
| 608 | + * @throws NullPointerException {@inheritDoc} | |
| 609 | + * @since 1.5 | |
| 610 | + */ | |
| 611 | + public <T extends Annotation> T getAnnotation(Class<T> annotationClass) { | |
| 612 | + if (annotationClass == null) | |
| 613 | + throw new NullPointerException(); | |
| 614 | + | |
| 615 | + return (T) declaredAnnotations().get(annotationClass); | |
| 616 | + } | |
| 617 | + | |
| 618 | + /** | |
| 619 | + * @since 1.5 | |
| 620 | + */ | |
| 621 | + public Annotation[] getDeclaredAnnotations() { | |
| 622 | + return AnnotationParser.toArray(declaredAnnotations()); | |
| 623 | + } | |
| 624 | + | |
| 625 | + private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations; | |
| 626 | + | |
| 627 | + private synchronized Map<Class<? extends Annotation>, Annotation> declaredAnnotations() { | |
| 628 | + if (declaredAnnotations == null) { | |
| 629 | + declaredAnnotations = AnnotationParser.parseAnnotations( | |
| 630 | + annotations, sun.misc.SharedSecrets.getJavaLangAccess(). | |
| 631 | + getConstantPool(getDeclaringClass()), | |
| 632 | + getDeclaringClass()); | |
| 633 | + } | |
| 634 | + return declaredAnnotations; | |
| 635 | + } | |
| 636 | + | |
| 637 | + /** | |
| 638 | + * Returns an array of arrays that represent the annotations on the formal | |
| 639 | + * parameters, in declaration order, of the method represented by | |
| 640 | + * this {@code Constructor} object. (Returns an array of length zero if the | |
| 641 | + * underlying method is parameterless. If the method has one or more | |
| 642 | + * parameters, a nested array of length zero is returned for each parameter | |
| 643 | + * with no annotations.) The annotation objects contained in the returned | |
| 644 | + * arrays are serializable. The caller of this method is free to modify | |
| 645 | + * the returned arrays; it will have no effect on the arrays returned to | |
| 646 | + * other callers. | |
| 647 | + * | |
| 648 | + * @return an array of arrays that represent the annotations on the formal | |
| 649 | + * parameters, in declaration order, of the method represented by this | |
| 650 | + * Constructor object | |
| 651 | + * @since 1.5 | |
| 652 | + */ | |
| 653 | + public Annotation[][] getParameterAnnotations() { | |
| 654 | + int numParameters = parameterTypes.length; | |
| 655 | + if (parameterAnnotations == null) | |
| 656 | + return new Annotation[numParameters][0]; | |
| 657 | + | |
| 658 | + Annotation[][] result = AnnotationParser.parseParameterAnnotations( | |
| 659 | + parameterAnnotations, | |
| 660 | + sun.misc.SharedSecrets.getJavaLangAccess(). | |
| 661 | + getConstantPool(getDeclaringClass()), | |
| 662 | + getDeclaringClass()); | |
| 663 | + if (result.length != numParameters) { | |
| 664 | + Class<?> declaringClass = getDeclaringClass(); | |
| 665 | + if (declaringClass.isEnum() || | |
| 666 | + declaringClass.isAnonymousClass() || | |
| 667 | + declaringClass.isLocalClass() ) | |
| 668 | + ; // Can't do reliable parameter counting | |
| 669 | + else { | |
| 670 | + if (!declaringClass.isMemberClass() || // top-level | |
| 671 | + // Check for the enclosing instance parameter for | |
| 672 | + // non-static member classes | |
| 673 | + (declaringClass.isMemberClass() && | |
| 674 | + ((declaringClass.getModifiers() & Modifier.STATIC) == 0) && | |
| 675 | + result.length + 1 != numParameters) ) { | |
| 676 | + throw new AnnotationFormatError( | |
| 677 | + "Parameter annotations don't match number of parameters"); | |
| 678 | + } | |
| 679 | + } | |
| 680 | + } | |
| 681 | + return result; | |
| 682 | + } | |
| 683 | +} | |
Binary file not shown.
| @@ -0,0 +1,1040 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.lang.reflect; | |
| 27 | + | |
| 28 | +import sun.reflect.FieldAccessor; | |
| 29 | +import sun.reflect.Reflection; | |
| 30 | +import sun.reflect.generics.repository.FieldRepository; | |
| 31 | +import sun.reflect.generics.factory.CoreReflectionFactory; | |
| 32 | +import sun.reflect.generics.factory.GenericsFactory; | |
| 33 | +import sun.reflect.generics.scope.ClassScope; | |
| 34 | +import java.lang.annotation.Annotation; | |
| 35 | +import java.util.Map; | |
| 36 | +import sun.reflect.annotation.AnnotationParser; | |
| 37 | + | |
| 38 | + | |
| 39 | +/** | |
| 40 | + * A {@code Field} provides information about, and dynamic access to, a | |
| 41 | + * single field of a class or an interface. The reflected field may | |
| 42 | + * be a class (static) field or an instance field. | |
| 43 | + * | |
| 44 | + * <p>A {@code Field} permits widening conversions to occur during a get or | |
| 45 | + * set access operation, but throws an {@code IllegalArgumentException} if a | |
| 46 | + * narrowing conversion would occur. | |
| 47 | + * | |
| 48 | + * @see Member | |
| 49 | + * @see java.lang.Class | |
| 50 | + * @see java.lang.Class#getFields() | |
| 51 | + * @see java.lang.Class#getField(String) | |
| 52 | + * @see java.lang.Class#getDeclaredFields() | |
| 53 | + * @see java.lang.Class#getDeclaredField(String) | |
| 54 | + * | |
| 55 | + * @author Kenneth Russell | |
| 56 | + * @author Nakul Saraiya | |
| 57 | + */ | |
| 58 | +public final | |
| 59 | +class Field extends AccessibleObject implements Member { | |
| 60 | + | |
| 61 | + private Class<?> clazz; | |
| 62 | + private int slot; | |
| 63 | + // This is guaranteed to be interned by the VM in the 1.4 | |
| 64 | + // reflection implementation | |
| 65 | + private String name; | |
| 66 | + private Class<?> type; | |
| 67 | + private int modifiers; | |
| 68 | + // Generics and annotations support | |
| 69 | + private transient String signature; | |
| 70 | + // generic info repository; lazily initialized | |
| 71 | + private transient FieldRepository genericInfo; | |
| 72 | + private byte[] annotations; | |
| 73 | + // Cached field accessor created without override | |
| 74 | + private FieldAccessor fieldAccessor; | |
| 75 | + // Cached field accessor created with override | |
| 76 | + private FieldAccessor overrideFieldAccessor; | |
| 77 | + // For sharing of FieldAccessors. This branching structure is | |
| 78 | + // currently only two levels deep (i.e., one root Field and | |
| 79 | + // potentially many Field objects pointing to it.) | |
| 80 | + private Field root; | |
| 81 | + | |
| 82 | + // Generics infrastructure | |
| 83 | + | |
| 84 | + private String getGenericSignature() {return signature;} | |
| 85 | + | |
| 86 | + // Accessor for factory | |
| 87 | + private GenericsFactory getFactory() { | |
| 88 | + Class<?> c = getDeclaringClass(); | |
| 89 | + // create scope and factory | |
| 90 | + return CoreReflectionFactory.make(c, ClassScope.make(c)); | |
| 91 | + } | |
| 92 | + | |
| 93 | + // Accessor for generic info repository | |
| 94 | + private FieldRepository getGenericInfo() { | |
| 95 | + // lazily initialize repository if necessary | |
| 96 | + if (genericInfo == null) { | |
| 97 | + // create and cache generic info repository | |
| 98 | + genericInfo = FieldRepository.make(getGenericSignature(), | |
| 99 | + getFactory()); | |
| 100 | + } | |
| 101 | + return genericInfo; //return cached repository | |
| 102 | + } | |
| 103 | + | |
| 104 | + | |
| 105 | + /** | |
| 106 | + * Package-private constructor used by ReflectAccess to enable | |
| 107 | + * instantiation of these objects in Java code from the java.lang | |
| 108 | + * package via sun.reflect.LangReflectAccess. | |
| 109 | + */ | |
| 110 | + Field(Class<?> declaringClass, | |
| 111 | + String name, | |
| 112 | + Class<?> type, | |
| 113 | + int modifiers, | |
| 114 | + int slot, | |
| 115 | + String signature, | |
| 116 | + byte[] annotations) | |
| 117 | + { | |
| 118 | + this.clazz = declaringClass; | |
| 119 | + this.name = name; | |
| 120 | + this.type = type; | |
| 121 | + this.modifiers = modifiers; | |
| 122 | + this.slot = slot; | |
| 123 | + this.signature = signature; | |
| 124 | + this.annotations = annotations; | |
| 125 | + } | |
| 126 | + | |
| 127 | + /** | |
| 128 | + * Package-private routine (exposed to java.lang.Class via | |
| 129 | + * ReflectAccess) which returns a copy of this Field. The copy's | |
| 130 | + * "root" field points to this Field. | |
| 131 | + */ | |
| 132 | + Field copy() { | |
| 133 | + // This routine enables sharing of FieldAccessor objects | |
| 134 | + // among Field objects which refer to the same underlying | |
| 135 | + // method in the VM. (All of this contortion is only necessary | |
| 136 | + // because of the "accessibility" bit in AccessibleObject, | |
| 137 | + // which implicitly requires that new java.lang.reflect | |
| 138 | + // objects be fabricated for each reflective call on Class | |
| 139 | + // objects.) | |
| 140 | + Field res = new Field(clazz, name, type, modifiers, slot, signature, annotations); | |
| 141 | + res.root = this; | |
| 142 | + // Might as well eagerly propagate this if already present | |
| 143 | + res.fieldAccessor = fieldAccessor; | |
| 144 | + res.overrideFieldAccessor = overrideFieldAccessor; | |
| 145 | + return res; | |
| 146 | + } | |
| 147 | + | |
| 148 | + /** | |
| 149 | + * Returns the {@code Class} object representing the class or interface | |
| 150 | + * that declares the field represented by this {@code Field} object. | |
| 151 | + */ | |
| 152 | + public Class<?> getDeclaringClass() { | |
| 153 | + return clazz; | |
| 154 | + } | |
| 155 | + | |
| 156 | + /** | |
| 157 | + * Returns the name of the field represented by this {@code Field} object. | |
| 158 | + */ | |
| 159 | + public String getName() { | |
| 160 | + return name; | |
| 161 | + } | |
| 162 | + | |
| 163 | + /** | |
| 164 | + * Returns the Java language modifiers for the field represented | |
| 165 | + * by this {@code Field} object, as an integer. The {@code Modifier} class should | |
| 166 | + * be used to decode the modifiers. | |
| 167 | + * | |
| 168 | + * @see Modifier | |
| 169 | + */ | |
| 170 | + public int getModifiers() { | |
| 171 | + return modifiers; | |
| 172 | + } | |
| 173 | + | |
| 174 | + /** | |
| 175 | + * Returns {@code true} if this field represents an element of | |
| 176 | + * an enumerated type; returns {@code false} otherwise. | |
| 177 | + * | |
| 178 | + * @return {@code true} if and only if this field represents an element of | |
| 179 | + * an enumerated type. | |
| 180 | + * @since 1.5 | |
| 181 | + */ | |
| 182 | + public boolean isEnumConstant() { | |
| 183 | + return (getModifiers() & Modifier.ENUM) != 0; | |
| 184 | + } | |
| 185 | + | |
| 186 | + /** | |
| 187 | + * Returns {@code true} if this field is a synthetic | |
| 188 | + * field; returns {@code false} otherwise. | |
| 189 | + * | |
| 190 | + * @return true if and only if this field is a synthetic | |
| 191 | + * field as defined by the Java Language Specification. | |
| 192 | + * @since 1.5 | |
| 193 | + */ | |
| 194 | + public boolean isSynthetic() { | |
| 195 | + return Modifier.isSynthetic(getModifiers()); | |
| 196 | + } | |
| 197 | + | |
| 198 | + /** | |
| 199 | + * Returns a {@code Class} object that identifies the | |
| 200 | + * declared type for the field represented by this | |
| 201 | + * {@code Field} object. | |
| 202 | + * | |
| 203 | + * @return a {@code Class} object identifying the declared | |
| 204 | + * type of the field represented by this object | |
| 205 | + */ | |
| 206 | + public Class<?> getType() { | |
| 207 | + return type; | |
| 208 | + } | |
| 209 | + | |
| 210 | + /** | |
| 211 | + * Returns a {@code Type} object that represents the declared type for | |
| 212 | + * the field represented by this {@code Field} object. | |
| 213 | + * | |
| 214 | + * <p>If the {@code Type} is a parameterized type, the | |
| 215 | + * {@code Type} object returned must accurately reflect the | |
| 216 | + * actual type parameters used in the source code. | |
| 217 | + * | |
| 218 | + * <p>If the type of the underlying field is a type variable or a | |
| 219 | + * parameterized type, it is created. Otherwise, it is resolved. | |
| 220 | + * | |
| 221 | + * @return a {@code Type} object that represents the declared type for | |
| 222 | + * the field represented by this {@code Field} object | |
| 223 | + * @throws GenericSignatureFormatError if the generic field | |
| 224 | + * signature does not conform to the format specified in | |
| 225 | + * <cite>The Java™ Virtual Machine Specification</cite> | |
| 226 | + * @throws TypeNotPresentException if the generic type | |
| 227 | + * signature of the underlying field refers to a non-existent | |
| 228 | + * type declaration | |
| 229 | + * @throws MalformedParameterizedTypeException if the generic | |
| 230 | + * signature of the underlying field refers to a parameterized type | |
| 231 | + * that cannot be instantiated for any reason | |
| 232 | + * @since 1.5 | |
| 233 | + */ | |
| 234 | + public Type getGenericType() { | |
| 235 | + if (getGenericSignature() != null) | |
| 236 | + return getGenericInfo().getGenericType(); | |
| 237 | + else | |
| 238 | + return getType(); | |
| 239 | + } | |
| 240 | + | |
| 241 | + | |
| 242 | + /** | |
| 243 | + * Compares this {@code Field} against the specified object. Returns | |
| 244 | + * true if the objects are the same. Two {@code Field} objects are the same if | |
| 245 | + * they were declared by the same class and have the same name | |
| 246 | + * and type. | |
| 247 | + */ | |
| 248 | + public boolean equals(Object obj) { | |
| 249 | + if (obj != null && obj instanceof Field) { | |
| 250 | + Field other = (Field)obj; | |
| 251 | + return (getDeclaringClass() == other.getDeclaringClass()) | |
| 252 | + && (getName() == other.getName()) | |
| 253 | + && (getType() == other.getType()); | |
| 254 | + } | |
| 255 | + return false; | |
| 256 | + } | |
| 257 | + | |
| 258 | + /** | |
| 259 | + * Returns a hashcode for this {@code Field}. This is computed as the | |
| 260 | + * exclusive-or of the hashcodes for the underlying field's | |
| 261 | + * declaring class name and its name. | |
| 262 | + */ | |
| 263 | + public int hashCode() { | |
| 264 | + return getDeclaringClass().getName().hashCode() ^ getName().hashCode(); | |
| 265 | + } | |
| 266 | + | |
| 267 | + /** | |
| 268 | + * Returns a string describing this {@code Field}. The format is | |
| 269 | + * the access modifiers for the field, if any, followed | |
| 270 | + * by the field type, followed by a space, followed by | |
| 271 | + * the fully-qualified name of the class declaring the field, | |
| 272 | + * followed by a period, followed by the name of the field. | |
| 273 | + * For example: | |
| 274 | + * <pre> | |
| 275 | + * public static final int java.lang.Thread.MIN_PRIORITY | |
| 276 | + * private int java.io.FileDescriptor.fd | |
| 277 | + * </pre> | |
| 278 | + * | |
| 279 | + * <p>The modifiers are placed in canonical order as specified by | |
| 280 | + * "The Java Language Specification". This is {@code public}, | |
| 281 | + * {@code protected} or {@code private} first, and then other | |
| 282 | + * modifiers in the following order: {@code static}, {@code final}, | |
| 283 | + * {@code transient}, {@code volatile}. | |
| 284 | + */ | |
| 285 | + public String toString() { | |
| 286 | + int mod = getModifiers(); | |
| 287 | + return (((mod == 0) ? "" : (Modifier.toString(mod) + " ")) | |
| 288 | + + getTypeName(getType()) + " " | |
| 289 | + + getTypeName(getDeclaringClass()) + "." | |
| 290 | + + getName()); | |
| 291 | + } | |
| 292 | + | |
| 293 | + /** | |
| 294 | + * Returns a string describing this {@code Field}, including | |
| 295 | + * its generic type. The format is the access modifiers for the | |
| 296 | + * field, if any, followed by the generic field type, followed by | |
| 297 | + * a space, followed by the fully-qualified name of the class | |
| 298 | + * declaring the field, followed by a period, followed by the name | |
| 299 | + * of the field. | |
| 300 | + * | |
| 301 | + * <p>The modifiers are placed in canonical order as specified by | |
| 302 | + * "The Java Language Specification". This is {@code public}, | |
| 303 | + * {@code protected} or {@code private} first, and then other | |
| 304 | + * modifiers in the following order: {@code static}, {@code final}, | |
| 305 | + * {@code transient}, {@code volatile}. | |
| 306 | + * | |
| 307 | + * @return a string describing this {@code Field}, including | |
| 308 | + * its generic type | |
| 309 | + * | |
| 310 | + * @since 1.5 | |
| 311 | + */ | |
| 312 | + public String toGenericString() { | |
| 313 | + int mod = getModifiers(); | |
| 314 | + Type fieldType = getGenericType(); | |
| 315 | + return (((mod == 0) ? "" : (Modifier.toString(mod) + " ")) | |
| 316 | + + ((fieldType instanceof Class) ? | |
| 317 | + getTypeName((Class)fieldType): fieldType.toString())+ " " | |
| 318 | + + getTypeName(getDeclaringClass()) + "." | |
| 319 | + + getName()); | |
| 320 | + } | |
| 321 | + | |
| 322 | + /** | |
| 323 | + * Returns the value of the field represented by this {@code Field}, on | |
| 324 | + * the specified object. The value is automatically wrapped in an | |
| 325 | + * object if it has a primitive type. | |
| 326 | + * | |
| 327 | + * <p>The underlying field's value is obtained as follows: | |
| 328 | + * | |
| 329 | + * <p>If the underlying field is a static field, the {@code obj} argument | |
| 330 | + * is ignored; it may be null. | |
| 331 | + * | |
| 332 | + * <p>Otherwise, the underlying field is an instance field. If the | |
| 333 | + * specified {@code obj} argument is null, the method throws a | |
| 334 | + * {@code NullPointerException}. If the specified object is not an | |
| 335 | + * instance of the class or interface declaring the underlying | |
| 336 | + * field, the method throws an {@code IllegalArgumentException}. | |
| 337 | + * | |
| 338 | + * <p>If this {@code Field} object is enforcing Java language access control, and | |
| 339 | + * the underlying field is inaccessible, the method throws an | |
| 340 | + * {@code IllegalAccessException}. | |
| 341 | + * If the underlying field is static, the class that declared the | |
| 342 | + * field is initialized if it has not already been initialized. | |
| 343 | + * | |
| 344 | + * <p>Otherwise, the value is retrieved from the underlying instance | |
| 345 | + * or static field. If the field has a primitive type, the value | |
| 346 | + * is wrapped in an object before being returned, otherwise it is | |
| 347 | + * returned as is. | |
| 348 | + * | |
| 349 | + * <p>If the field is hidden in the type of {@code obj}, | |
| 350 | + * the field's value is obtained according to the preceding rules. | |
| 351 | + * | |
| 352 | + * @param obj object from which the represented field's value is | |
| 353 | + * to be extracted | |
| 354 | + * @return the value of the represented field in object | |
| 355 | + * {@code obj}; primitive values are wrapped in an appropriate | |
| 356 | + * object before being returned | |
| 357 | + * | |
| 358 | + * @exception IllegalAccessException if this {@code Field} object | |
| 359 | + * is enforcing Java language access control and the underlying | |
| 360 | + * field is inaccessible. | |
| 361 | + * @exception IllegalArgumentException if the specified object is not an | |
| 362 | + * instance of the class or interface declaring the underlying | |
| 363 | + * field (or a subclass or implementor thereof). | |
| 364 | + * @exception NullPointerException if the specified object is null | |
| 365 | + * and the field is an instance field. | |
| 366 | + * @exception ExceptionInInitializerError if the initialization provoked | |
| 367 | + * by this method fails. | |
| 368 | + */ | |
| 369 | + public Object get(Object obj) | |
| 370 | + throws IllegalArgumentException, IllegalAccessException | |
| 371 | + { | |
| 372 | + return getFieldAccessor(obj).get(obj); | |
| 373 | + } | |
| 374 | + | |
| 375 | + /** | |
| 376 | + * Gets the value of a static or instance {@code boolean} field. | |
| 377 | + * | |
| 378 | + * @param obj the object to extract the {@code boolean} value | |
| 379 | + * from | |
| 380 | + * @return the value of the {@code boolean} field | |
| 381 | + * | |
| 382 | + * @exception IllegalAccessException if this {@code Field} object | |
| 383 | + * is enforcing Java language access control and the underlying | |
| 384 | + * field is inaccessible. | |
| 385 | + * @exception IllegalArgumentException if the specified object is not | |
| 386 | + * an instance of the class or interface declaring the | |
| 387 | + * underlying field (or a subclass or implementor | |
| 388 | + * thereof), or if the field value cannot be | |
| 389 | + * converted to the type {@code boolean} by a | |
| 390 | + * widening conversion. | |
| 391 | + * @exception NullPointerException if the specified object is null | |
| 392 | + * and the field is an instance field. | |
| 393 | + * @exception ExceptionInInitializerError if the initialization provoked | |
| 394 | + * by this method fails. | |
| 395 | + * @see Field#get | |
| 396 | + */ | |
| 397 | + public boolean getBoolean(Object obj) | |
| 398 | + throws IllegalArgumentException, IllegalAccessException | |
| 399 | + { | |
| 400 | + return getFieldAccessor(obj).getBoolean(obj); | |
| 401 | + } | |
| 402 | + | |
| 403 | + /** | |
| 404 | + * Gets the value of a static or instance {@code byte} field. | |
| 405 | + * | |
| 406 | + * @param obj the object to extract the {@code byte} value | |
| 407 | + * from | |
| 408 | + * @return the value of the {@code byte} field | |
| 409 | + * | |
| 410 | + * @exception IllegalAccessException if this {@code Field} object | |
| 411 | + * is enforcing Java language access control and the underlying | |
| 412 | + * field is inaccessible. | |
| 413 | + * @exception IllegalArgumentException if the specified object is not | |
| 414 | + * an instance of the class or interface declaring the | |
| 415 | + * underlying field (or a subclass or implementor | |
| 416 | + * thereof), or if the field value cannot be | |
| 417 | + * converted to the type {@code byte} by a | |
| 418 | + * widening conversion. | |
| 419 | + * @exception NullPointerException if the specified object is null | |
| 420 | + * and the field is an instance field. | |
| 421 | + * @exception ExceptionInInitializerError if the initialization provoked | |
| 422 | + * by this method fails. | |
| 423 | + * @see Field#get | |
| 424 | + */ | |
| 425 | + public byte getByte(Object obj) | |
| 426 | + throws IllegalArgumentException, IllegalAccessException | |
| 427 | + { | |
| 428 | + return getFieldAccessor(obj).getByte(obj); | |
| 429 | + } | |
| 430 | + | |
| 431 | + /** | |
| 432 | + * Gets the value of a static or instance field of type | |
| 433 | + * {@code char} or of another primitive type convertible to | |
| 434 | + * type {@code char} via a widening conversion. | |
| 435 | + * | |
| 436 | + * @param obj the object to extract the {@code char} value | |
| 437 | + * from | |
| 438 | + * @return the value of the field converted to type {@code char} | |
| 439 | + * | |
| 440 | + * @exception IllegalAccessException if this {@code Field} object | |
| 441 | + * is enforcing Java language access control and the underlying | |
| 442 | + * field is inaccessible. | |
| 443 | + * @exception IllegalArgumentException if the specified object is not | |
| 444 | + * an instance of the class or interface declaring the | |
| 445 | + * underlying field (or a subclass or implementor | |
| 446 | + * thereof), or if the field value cannot be | |
| 447 | + * converted to the type {@code char} by a | |
| 448 | + * widening conversion. | |
| 449 | + * @exception NullPointerException if the specified object is null | |
| 450 | + * and the field is an instance field. | |
| 451 | + * @exception ExceptionInInitializerError if the initialization provoked | |
| 452 | + * by this method fails. | |
| 453 | + * @see Field#get | |
| 454 | + */ | |
| 455 | + public char getChar(Object obj) | |
| 456 | + throws IllegalArgumentException, IllegalAccessException | |
| 457 | + { | |
| 458 | + return getFieldAccessor(obj).getChar(obj); | |
| 459 | + } | |
| 460 | + | |
| 461 | + /** | |
| 462 | + * Gets the value of a static or instance field of type | |
| 463 | + * {@code short} or of another primitive type convertible to | |
| 464 | + * type {@code short} via a widening conversion. | |
| 465 | + * | |
| 466 | + * @param obj the object to extract the {@code short} value | |
| 467 | + * from | |
| 468 | + * @return the value of the field converted to type {@code short} | |
| 469 | + * | |
| 470 | + * @exception IllegalAccessException if this {@code Field} object | |
| 471 | + * is enforcing Java language access control and the underlying | |
| 472 | + * field is inaccessible. | |
| 473 | + * @exception IllegalArgumentException if the specified object is not | |
| 474 | + * an instance of the class or interface declaring the | |
| 475 | + * underlying field (or a subclass or implementor | |
| 476 | + * thereof), or if the field value cannot be | |
| 477 | + * converted to the type {@code short} by a | |
| 478 | + * widening conversion. | |
| 479 | + * @exception NullPointerException if the specified object is null | |
| 480 | + * and the field is an instance field. | |
| 481 | + * @exception ExceptionInInitializerError if the initialization provoked | |
| 482 | + * by this method fails. | |
| 483 | + * @see Field#get | |
| 484 | + */ | |
| 485 | + public short getShort(Object obj) | |
| 486 | + throws IllegalArgumentException, IllegalAccessException | |
| 487 | + { | |
| 488 | + return getFieldAccessor(obj).getShort(obj); | |
| 489 | + } | |
| 490 | + | |
| 491 | + /** | |
| 492 | + * Gets the value of a static or instance field of type | |
| 493 | + * {@code int} or of another primitive type convertible to | |
| 494 | + * type {@code int} via a widening conversion. | |
| 495 | + * | |
| 496 | + * @param obj the object to extract the {@code int} value | |
| 497 | + * from | |
| 498 | + * @return the value of the field converted to type {@code int} | |
| 499 | + * | |
| 500 | + * @exception IllegalAccessException if this {@code Field} object | |
| 501 | + * is enforcing Java language access control and the underlying | |
| 502 | + * field is inaccessible. | |
| 503 | + * @exception IllegalArgumentException if the specified object is not | |
| 504 | + * an instance of the class or interface declaring the | |
| 505 | + * underlying field (or a subclass or implementor | |
| 506 | + * thereof), or if the field value cannot be | |
| 507 | + * converted to the type {@code int} by a | |
| 508 | + * widening conversion. | |
| 509 | + * @exception NullPointerException if the specified object is null | |
| 510 | + * and the field is an instance field. | |
| 511 | + * @exception ExceptionInInitializerError if the initialization provoked | |
| 512 | + * by this method fails. | |
| 513 | + * @see Field#get | |
| 514 | + */ | |
| 515 | + public int getInt(Object obj) | |
| 516 | + throws IllegalArgumentException, IllegalAccessException | |
| 517 | + { | |
| 518 | + return getFieldAccessor(obj).getInt(obj); | |
| 519 | + } | |
| 520 | + | |
| 521 | + /** | |
| 522 | + * Gets the value of a static or instance field of type | |
| 523 | + * {@code long} or of another primitive type convertible to | |
| 524 | + * type {@code long} via a widening conversion. | |
| 525 | + * | |
| 526 | + * @param obj the object to extract the {@code long} value | |
| 527 | + * from | |
| 528 | + * @return the value of the field converted to type {@code long} | |
| 529 | + * | |
| 530 | + * @exception IllegalAccessException if this {@code Field} object | |
| 531 | + * is enforcing Java language access control and the underlying | |
| 532 | + * field is inaccessible. | |
| 533 | + * @exception IllegalArgumentException if the specified object is not | |
| 534 | + * an instance of the class or interface declaring the | |
| 535 | + * underlying field (or a subclass or implementor | |
| 536 | + * thereof), or if the field value cannot be | |
| 537 | + * converted to the type {@code long} by a | |
| 538 | + * widening conversion. | |
| 539 | + * @exception NullPointerException if the specified object is null | |
| 540 | + * and the field is an instance field. | |
| 541 | + * @exception ExceptionInInitializerError if the initialization provoked | |
| 542 | + * by this method fails. | |
| 543 | + * @see Field#get | |
| 544 | + */ | |
| 545 | + public long getLong(Object obj) | |
| 546 | + throws IllegalArgumentException, IllegalAccessException | |
| 547 | + { | |
| 548 | + return getFieldAccessor(obj).getLong(obj); | |
| 549 | + } | |
| 550 | + | |
| 551 | + /** | |
| 552 | + * Gets the value of a static or instance field of type | |
| 553 | + * {@code float} or of another primitive type convertible to | |
| 554 | + * type {@code float} via a widening conversion. | |
| 555 | + * | |
| 556 | + * @param obj the object to extract the {@code float} value | |
| 557 | + * from | |
| 558 | + * @return the value of the field converted to type {@code float} | |
| 559 | + * | |
| 560 | + * @exception IllegalAccessException if this {@code Field} object | |
| 561 | + * is enforcing Java language access control and the underlying | |
| 562 | + * field is inaccessible. | |
| 563 | + * @exception IllegalArgumentException if the specified object is not | |
| 564 | + * an instance of the class or interface declaring the | |
| 565 | + * underlying field (or a subclass or implementor | |
| 566 | + * thereof), or if the field value cannot be | |
| 567 | + * converted to the type {@code float} by a | |
| 568 | + * widening conversion. | |
| 569 | + * @exception NullPointerException if the specified object is null | |
| 570 | + * and the field is an instance field. | |
| 571 | + * @exception ExceptionInInitializerError if the initialization provoked | |
| 572 | + * by this method fails. | |
| 573 | + * @see Field#get | |
| 574 | + */ | |
| 575 | + public float getFloat(Object obj) | |
| 576 | + throws IllegalArgumentException, IllegalAccessException | |
| 577 | + { | |
| 578 | + return getFieldAccessor(obj).getFloat(obj); | |
| 579 | + } | |
| 580 | + | |
| 581 | + /** | |
| 582 | + * Gets the value of a static or instance field of type | |
| 583 | + * {@code double} or of another primitive type convertible to | |
| 584 | + * type {@code double} via a widening conversion. | |
| 585 | + * | |
| 586 | + * @param obj the object to extract the {@code double} value | |
| 587 | + * from | |
| 588 | + * @return the value of the field converted to type {@code double} | |
| 589 | + * | |
| 590 | + * @exception IllegalAccessException if this {@code Field} object | |
| 591 | + * is enforcing Java language access control and the underlying | |
| 592 | + * field is inaccessible. | |
| 593 | + * @exception IllegalArgumentException if the specified object is not | |
| 594 | + * an instance of the class or interface declaring the | |
| 595 | + * underlying field (or a subclass or implementor | |
| 596 | + * thereof), or if the field value cannot be | |
| 597 | + * converted to the type {@code double} by a | |
| 598 | + * widening conversion. | |
| 599 | + * @exception NullPointerException if the specified object is null | |
| 600 | + * and the field is an instance field. | |
| 601 | + * @exception ExceptionInInitializerError if the initialization provoked | |
| 602 | + * by this method fails. | |
| 603 | + * @see Field#get | |
| 604 | + */ | |
| 605 | + public double getDouble(Object obj) | |
| 606 | + throws IllegalArgumentException, IllegalAccessException | |
| 607 | + { | |
| 608 | + return getFieldAccessor(obj).getDouble(obj); | |
| 609 | + } | |
| 610 | + | |
| 611 | + /** | |
| 612 | + * Sets the field represented by this {@code Field} object on the | |
| 613 | + * specified object argument to the specified new value. The new | |
| 614 | + * value is automatically unwrapped if the underlying field has a | |
| 615 | + * primitive type. | |
| 616 | + * | |
| 617 | + * <p>The operation proceeds as follows: | |
| 618 | + * | |
| 619 | + * <p>If the underlying field is static, the {@code obj} argument is | |
| 620 | + * ignored; it may be null. | |
| 621 | + * | |
| 622 | + * <p>Otherwise the underlying field is an instance field. If the | |
| 623 | + * specified object argument is null, the method throws a | |
| 624 | + * {@code NullPointerException}. If the specified object argument is not | |
| 625 | + * an instance of the class or interface declaring the underlying | |
| 626 | + * field, the method throws an {@code IllegalArgumentException}. | |
| 627 | + * | |
| 628 | + * <p>If this {@code Field} object is enforcing Java language access control, and | |
| 629 | + * the underlying field is inaccessible, the method throws an | |
| 630 | + * {@code IllegalAccessException}. | |
| 631 | + * | |
| 632 | + * <p>If the underlying field is final, the method throws an | |
| 633 | + * {@code IllegalAccessException} unless {@code setAccessible(true)} | |
| 634 | + * has succeeded for this {@code Field} object | |
| 635 | + * and the field is non-static. Setting a final field in this way | |
| 636 | + * is meaningful only during deserialization or reconstruction of | |
| 637 | + * instances of classes with blank final fields, before they are | |
| 638 | + * made available for access by other parts of a program. Use in | |
| 639 | + * any other context may have unpredictable effects, including cases | |
| 640 | + * in which other parts of a program continue to use the original | |
| 641 | + * value of this field. | |
| 642 | + * | |
| 643 | + * <p>If the underlying field is of a primitive type, an unwrapping | |
| 644 | + * conversion is attempted to convert the new value to a value of | |
| 645 | + * a primitive type. If this attempt fails, the method throws an | |
| 646 | + * {@code IllegalArgumentException}. | |
| 647 | + * | |
| 648 | + * <p>If, after possible unwrapping, the new value cannot be | |
| 649 | + * converted to the type of the underlying field by an identity or | |
| 650 | + * widening conversion, the method throws an | |
| 651 | + * {@code IllegalArgumentException}. | |
| 652 | + * | |
| 653 | + * <p>If the underlying field is static, the class that declared the | |
| 654 | + * field is initialized if it has not already been initialized. | |
| 655 | + * | |
| 656 | + * <p>The field is set to the possibly unwrapped and widened new value. | |
| 657 | + * | |
| 658 | + * <p>If the field is hidden in the type of {@code obj}, | |
| 659 | + * the field's value is set according to the preceding rules. | |
| 660 | + * | |
| 661 | + * @param obj the object whose field should be modified | |
| 662 | + * @param value the new value for the field of {@code obj} | |
| 663 | + * being modified | |
| 664 | + * | |
| 665 | + * @exception IllegalAccessException if this {@code Field} object | |
| 666 | + * is enforcing Java language access control and the underlying | |
| 667 | + * field is either inaccessible or final. | |
| 668 | + * @exception IllegalArgumentException if the specified object is not an | |
| 669 | + * instance of the class or interface declaring the underlying | |
| 670 | + * field (or a subclass or implementor thereof), | |
| 671 | + * or if an unwrapping conversion fails. | |
| 672 | + * @exception NullPointerException if the specified object is null | |
| 673 | + * and the field is an instance field. | |
| 674 | + * @exception ExceptionInInitializerError if the initialization provoked | |
| 675 | + * by this method fails. | |
| 676 | + */ | |
| 677 | + public void set(Object obj, Object value) | |
| 678 | + throws IllegalArgumentException, IllegalAccessException | |
| 679 | + { | |
| 680 | + getFieldAccessor(obj).set(obj, value); | |
| 681 | + } | |
| 682 | + | |
| 683 | + /** | |
| 684 | + * Sets the value of a field as a {@code boolean} on the specified object. | |
| 685 | + * This method is equivalent to | |
| 686 | + * {@code set(obj, zObj)}, | |
| 687 | + * where {@code zObj} is a {@code Boolean} object and | |
| 688 | + * {@code zObj.booleanValue() == z}. | |
| 689 | + * | |
| 690 | + * @param obj the object whose field should be modified | |
| 691 | + * @param z the new value for the field of {@code obj} | |
| 692 | + * being modified | |
| 693 | + * | |
| 694 | + * @exception IllegalAccessException if this {@code Field} object | |
| 695 | + * is enforcing Java language access control and the underlying | |
| 696 | + * field is either inaccessible or final. | |
| 697 | + * @exception IllegalArgumentException if the specified object is not an | |
| 698 | + * instance of the class or interface declaring the underlying | |
| 699 | + * field (or a subclass or implementor thereof), | |
| 700 | + * or if an unwrapping conversion fails. | |
| 701 | + * @exception NullPointerException if the specified object is null | |
| 702 | + * and the field is an instance field. | |
| 703 | + * @exception ExceptionInInitializerError if the initialization provoked | |
| 704 | + * by this method fails. | |
| 705 | + * @see Field#set | |
| 706 | + */ | |
| 707 | + public void setBoolean(Object obj, boolean z) | |
| 708 | + throws IllegalArgumentException, IllegalAccessException | |
| 709 | + { | |
| 710 | + getFieldAccessor(obj).setBoolean(obj, z); | |
| 711 | + } | |
| 712 | + | |
| 713 | + /** | |
| 714 | + * Sets the value of a field as a {@code byte} on the specified object. | |
| 715 | + * This method is equivalent to | |
| 716 | + * {@code set(obj, bObj)}, | |
| 717 | + * where {@code bObj} is a {@code Byte} object and | |
| 718 | + * {@code bObj.byteValue() == b}. | |
| 719 | + * | |
| 720 | + * @param obj the object whose field should be modified | |
| 721 | + * @param b the new value for the field of {@code obj} | |
| 722 | + * being modified | |
| 723 | + * | |
| 724 | + * @exception IllegalAccessException if this {@code Field} object | |
| 725 | + * is enforcing Java language access control and the underlying | |
| 726 | + * field is either inaccessible or final. | |
| 727 | + * @exception IllegalArgumentException if the specified object is not an | |
| 728 | + * instance of the class or interface declaring the underlying | |
| 729 | + * field (or a subclass or implementor thereof), | |
| 730 | + * or if an unwrapping conversion fails. | |
| 731 | + * @exception NullPointerException if the specified object is null | |
| 732 | + * and the field is an instance field. | |
| 733 | + * @exception ExceptionInInitializerError if the initialization provoked | |
| 734 | + * by this method fails. | |
| 735 | + * @see Field#set | |
| 736 | + */ | |
| 737 | + public void setByte(Object obj, byte b) | |
| 738 | + throws IllegalArgumentException, IllegalAccessException | |
| 739 | + { | |
| 740 | + getFieldAccessor(obj).setByte(obj, b); | |
| 741 | + } | |
| 742 | + | |
| 743 | + /** | |
| 744 | + * Sets the value of a field as a {@code char} on the specified object. | |
| 745 | + * This method is equivalent to | |
| 746 | + * {@code set(obj, cObj)}, | |
| 747 | + * where {@code cObj} is a {@code Character} object and | |
| 748 | + * {@code cObj.charValue() == c}. | |
| 749 | + * | |
| 750 | + * @param obj the object whose field should be modified | |
| 751 | + * @param c the new value for the field of {@code obj} | |
| 752 | + * being modified | |
| 753 | + * | |
| 754 | + * @exception IllegalAccessException if this {@code Field} object | |
| 755 | + * is enforcing Java language access control and the underlying | |
| 756 | + * field is either inaccessible or final. | |
| 757 | + * @exception IllegalArgumentException if the specified object is not an | |
| 758 | + * instance of the class or interface declaring the underlying | |
| 759 | + * field (or a subclass or implementor thereof), | |
| 760 | + * or if an unwrapping conversion fails. | |
| 761 | + * @exception NullPointerException if the specified object is null | |
| 762 | + * and the field is an instance field. | |
| 763 | + * @exception ExceptionInInitializerError if the initialization provoked | |
| 764 | + * by this method fails. | |
| 765 | + * @see Field#set | |
| 766 | + */ | |
| 767 | + public void setChar(Object obj, char c) | |
| 768 | + throws IllegalArgumentException, IllegalAccessException | |
| 769 | + { | |
| 770 | + getFieldAccessor(obj).setChar(obj, c); | |
| 771 | + } | |
| 772 | + | |
| 773 | + /** | |
| 774 | + * Sets the value of a field as a {@code short} on the specified object. | |
| 775 | + * This method is equivalent to | |
| 776 | + * {@code set(obj, sObj)}, | |
| 777 | + * where {@code sObj} is a {@code Short} object and | |
| 778 | + * {@code sObj.shortValue() == s}. | |
| 779 | + * | |
| 780 | + * @param obj the object whose field should be modified | |
| 781 | + * @param s the new value for the field of {@code obj} | |
| 782 | + * being modified | |
| 783 | + * | |
| 784 | + * @exception IllegalAccessException if this {@code Field} object | |
| 785 | + * is enforcing Java language access control and the underlying | |
| 786 | + * field is either inaccessible or final. | |
| 787 | + * @exception IllegalArgumentException if the specified object is not an | |
| 788 | + * instance of the class or interface declaring the underlying | |
| 789 | + * field (or a subclass or implementor thereof), | |
| 790 | + * or if an unwrapping conversion fails. | |
| 791 | + * @exception NullPointerException if the specified object is null | |
| 792 | + * and the field is an instance field. | |
| 793 | + * @exception ExceptionInInitializerError if the initialization provoked | |
| 794 | + * by this method fails. | |
| 795 | + * @see Field#set | |
| 796 | + */ | |
| 797 | + public void setShort(Object obj, short s) | |
| 798 | + throws IllegalArgumentException, IllegalAccessException | |
| 799 | + { | |
| 800 | + getFieldAccessor(obj).setShort(obj, s); | |
| 801 | + } | |
| 802 | + | |
| 803 | + /** | |
| 804 | + * Sets the value of a field as an {@code int} on the specified object. | |
| 805 | + * This method is equivalent to | |
| 806 | + * {@code set(obj, iObj)}, | |
| 807 | + * where {@code iObj} is a {@code Integer} object and | |
| 808 | + * {@code iObj.intValue() == i}. | |
| 809 | + * | |
| 810 | + * @param obj the object whose field should be modified | |
| 811 | + * @param i the new value for the field of {@code obj} | |
| 812 | + * being modified | |
| 813 | + * | |
| 814 | + * @exception IllegalAccessException if this {@code Field} object | |
| 815 | + * is enforcing Java language access control and the underlying | |
| 816 | + * field is either inaccessible or final. | |
| 817 | + * @exception IllegalArgumentException if the specified object is not an | |
| 818 | + * instance of the class or interface declaring the underlying | |
| 819 | + * field (or a subclass or implementor thereof), | |
| 820 | + * or if an unwrapping conversion fails. | |
| 821 | + * @exception NullPointerException if the specified object is null | |
| 822 | + * and the field is an instance field. | |
| 823 | + * @exception ExceptionInInitializerError if the initialization provoked | |
| 824 | + * by this method fails. | |
| 825 | + * @see Field#set | |
| 826 | + */ | |
| 827 | + public void setInt(Object obj, int i) | |
| 828 | + throws IllegalArgumentException, IllegalAccessException | |
| 829 | + { | |
| 830 | + getFieldAccessor(obj).setInt(obj, i); | |
| 831 | + } | |
| 832 | + | |
| 833 | + /** | |
| 834 | + * Sets the value of a field as a {@code long} on the specified object. | |
| 835 | + * This method is equivalent to | |
| 836 | + * {@code set(obj, lObj)}, | |
| 837 | + * where {@code lObj} is a {@code Long} object and | |
| 838 | + * {@code lObj.longValue() == l}. | |
| 839 | + * | |
| 840 | + * @param obj the object whose field should be modified | |
| 841 | + * @param l the new value for the field of {@code obj} | |
| 842 | + * being modified | |
| 843 | + * | |
| 844 | + * @exception IllegalAccessException if this {@code Field} object | |
| 845 | + * is enforcing Java language access control and the underlying | |
| 846 | + * field is either inaccessible or final. | |
| 847 | + * @exception IllegalArgumentException if the specified object is not an | |
| 848 | + * instance of the class or interface declaring the underlying | |
| 849 | + * field (or a subclass or implementor thereof), | |
| 850 | + * or if an unwrapping conversion fails. | |
| 851 | + * @exception NullPointerException if the specified object is null | |
| 852 | + * and the field is an instance field. | |
| 853 | + * @exception ExceptionInInitializerError if the initialization provoked | |
| 854 | + * by this method fails. | |
| 855 | + * @see Field#set | |
| 856 | + */ | |
| 857 | + public void setLong(Object obj, long l) | |
| 858 | + throws IllegalArgumentException, IllegalAccessException | |
| 859 | + { | |
| 860 | + getFieldAccessor(obj).setLong(obj, l); | |
| 861 | + } | |
| 862 | + | |
| 863 | + /** | |
| 864 | + * Sets the value of a field as a {@code float} on the specified object. | |
| 865 | + * This method is equivalent to | |
| 866 | + * {@code set(obj, fObj)}, | |
| 867 | + * where {@code fObj} is a {@code Float} object and | |
| 868 | + * {@code fObj.floatValue() == f}. | |
| 869 | + * | |
| 870 | + * @param obj the object whose field should be modified | |
| 871 | + * @param f the new value for the field of {@code obj} | |
| 872 | + * being modified | |
| 873 | + * | |
| 874 | + * @exception IllegalAccessException if this {@code Field} object | |
| 875 | + * is enforcing Java language access control and the underlying | |
| 876 | + * field is either inaccessible or final. | |
| 877 | + * @exception IllegalArgumentException if the specified object is not an | |
| 878 | + * instance of the class or interface declaring the underlying | |
| 879 | + * field (or a subclass or implementor thereof), | |
| 880 | + * or if an unwrapping conversion fails. | |
| 881 | + * @exception NullPointerException if the specified object is null | |
| 882 | + * and the field is an instance field. | |
| 883 | + * @exception ExceptionInInitializerError if the initialization provoked | |
| 884 | + * by this method fails. | |
| 885 | + * @see Field#set | |
| 886 | + */ | |
| 887 | + public void setFloat(Object obj, float f) | |
| 888 | + throws IllegalArgumentException, IllegalAccessException | |
| 889 | + { | |
| 890 | + getFieldAccessor(obj).setFloat(obj, f); | |
| 891 | + } | |
| 892 | + | |
| 893 | + /** | |
| 894 | + * Sets the value of a field as a {@code double} on the specified object. | |
| 895 | + * This method is equivalent to | |
| 896 | + * {@code set(obj, dObj)}, | |
| 897 | + * where {@code dObj} is a {@code Double} object and | |
| 898 | + * {@code dObj.doubleValue() == d}. | |
| 899 | + * | |
| 900 | + * @param obj the object whose field should be modified | |
| 901 | + * @param d the new value for the field of {@code obj} | |
| 902 | + * being modified | |
| 903 | + * | |
| 904 | + * @exception IllegalAccessException if this {@code Field} object | |
| 905 | + * is enforcing Java language access control and the underlying | |
| 906 | + * field is either inaccessible or final. | |
| 907 | + * @exception IllegalArgumentException if the specified object is not an | |
| 908 | + * instance of the class or interface declaring the underlying | |
| 909 | + * field (or a subclass or implementor thereof), | |
| 910 | + * or if an unwrapping conversion fails. | |
| 911 | + * @exception NullPointerException if the specified object is null | |
| 912 | + * and the field is an instance field. | |
| 913 | + * @exception ExceptionInInitializerError if the initialization provoked | |
| 914 | + * by this method fails. | |
| 915 | + * @see Field#set | |
| 916 | + */ | |
| 917 | + public void setDouble(Object obj, double d) | |
| 918 | + throws IllegalArgumentException, IllegalAccessException | |
| 919 | + { | |
| 920 | + getFieldAccessor(obj).setDouble(obj, d); | |
| 921 | + } | |
| 922 | + | |
| 923 | + // Convenience routine which performs security checks | |
| 924 | + private FieldAccessor getFieldAccessor(Object obj) | |
| 925 | + throws IllegalAccessException | |
| 926 | + { | |
| 927 | + doSecurityCheck(obj); | |
| 928 | + boolean ov = override; | |
| 929 | + FieldAccessor a = (ov)? overrideFieldAccessor : fieldAccessor; | |
| 930 | + return (a != null)? a : acquireFieldAccessor(ov); | |
| 931 | + } | |
| 932 | + | |
| 933 | + // NOTE that there is no synchronization used here. It is correct | |
| 934 | + // (though not efficient) to generate more than one FieldAccessor | |
| 935 | + // for a given Field. However, avoiding synchronization will | |
| 936 | + // probably make the implementation more scalable. | |
| 937 | + private FieldAccessor acquireFieldAccessor(boolean overrideFinalCheck) { | |
| 938 | + // First check to see if one has been created yet, and take it | |
| 939 | + // if so | |
| 940 | + FieldAccessor tmp = null; | |
| 941 | + if (root != null) tmp = root.getFieldAccessor(overrideFinalCheck); | |
| 942 | + if (tmp != null) { | |
| 943 | + if (overrideFinalCheck) | |
| 944 | + overrideFieldAccessor = tmp; | |
| 945 | + else | |
| 946 | + fieldAccessor = tmp; | |
| 947 | + } else { | |
| 948 | + // Otherwise fabricate one and propagate it up to the root | |
| 949 | + tmp = reflectionFactory.newFieldAccessor(this, overrideFinalCheck); | |
| 950 | + setFieldAccessor(tmp, overrideFinalCheck); | |
| 951 | + } | |
| 952 | + | |
| 953 | + return tmp; | |
| 954 | + } | |
| 955 | + | |
| 956 | + // Returns FieldAccessor for this Field object, not looking up | |
| 957 | + // the chain to the root | |
| 958 | + private FieldAccessor getFieldAccessor(boolean overrideFinalCheck) { | |
| 959 | + return (overrideFinalCheck)? overrideFieldAccessor : fieldAccessor; | |
| 960 | + } | |
| 961 | + | |
| 962 | + // Sets the FieldAccessor for this Field object and | |
| 963 | + // (recursively) its root | |
| 964 | + private void setFieldAccessor(FieldAccessor accessor, boolean overrideFinalCheck) { | |
| 965 | + if (overrideFinalCheck) | |
| 966 | + overrideFieldAccessor = accessor; | |
| 967 | + else | |
| 968 | + fieldAccessor = accessor; | |
| 969 | + // Propagate up | |
| 970 | + if (root != null) { | |
| 971 | + root.setFieldAccessor(accessor, overrideFinalCheck); | |
| 972 | + } | |
| 973 | + } | |
| 974 | + | |
| 975 | + // NOTE: be very careful if you change the stack depth of this | |
| 976 | + // routine. The depth of the "getCallerClass" call is hardwired so | |
| 977 | + // that the compiler can have an easier time if this gets inlined. | |
| 978 | + private void doSecurityCheck(Object obj) throws IllegalAccessException { | |
| 979 | + if (!override) { | |
| 980 | + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { | |
| 981 | + Class<?> caller = Reflection.getCallerClass(4); | |
| 982 | + | |
| 983 | + checkAccess(caller, clazz, obj, modifiers); | |
| 984 | + } | |
| 985 | + } | |
| 986 | + } | |
| 987 | + | |
| 988 | + /* | |
| 989 | + * Utility routine to paper over array type names | |
| 990 | + */ | |
| 991 | + static String getTypeName(Class<?> type) { | |
| 992 | + if (type.isArray()) { | |
| 993 | + try { | |
| 994 | + Class<?> cl = type; | |
| 995 | + int dimensions = 0; | |
| 996 | + while (cl.isArray()) { | |
| 997 | + dimensions++; | |
| 998 | + cl = cl.getComponentType(); | |
| 999 | + } | |
| 1000 | + StringBuffer sb = new StringBuffer(); | |
| 1001 | + sb.append(cl.getName()); | |
| 1002 | + for (int i = 0; i < dimensions; i++) { | |
| 1003 | + sb.append("[]"); | |
| 1004 | + } | |
| 1005 | + return sb.toString(); | |
| 1006 | + } catch (Throwable e) { /*FALLTHRU*/ } | |
| 1007 | + } | |
| 1008 | + return type.getName(); | |
| 1009 | + } | |
| 1010 | + | |
| 1011 | + /** | |
| 1012 | + * @throws NullPointerException {@inheritDoc} | |
| 1013 | + * @since 1.5 | |
| 1014 | + */ | |
| 1015 | + public <T extends Annotation> T getAnnotation(Class<T> annotationClass) { | |
| 1016 | + if (annotationClass == null) | |
| 1017 | + throw new NullPointerException(); | |
| 1018 | + | |
| 1019 | + return (T) declaredAnnotations().get(annotationClass); | |
| 1020 | + } | |
| 1021 | + | |
| 1022 | + /** | |
| 1023 | + * @since 1.5 | |
| 1024 | + */ | |
| 1025 | + public Annotation[] getDeclaredAnnotations() { | |
| 1026 | + return AnnotationParser.toArray(declaredAnnotations()); | |
| 1027 | + } | |
| 1028 | + | |
| 1029 | + private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations; | |
| 1030 | + | |
| 1031 | + private synchronized Map<Class<? extends Annotation>, Annotation> declaredAnnotations() { | |
| 1032 | + if (declaredAnnotations == null) { | |
| 1033 | + declaredAnnotations = AnnotationParser.parseAnnotations( | |
| 1034 | + annotations, sun.misc.SharedSecrets.getJavaLangAccess(). | |
| 1035 | + getConstantPool(getDeclaringClass()), | |
| 1036 | + getDeclaringClass()); | |
| 1037 | + } | |
| 1038 | + return declaredAnnotations; | |
| 1039 | + } | |
| 1040 | +} | |
Binary file not shown.
| @@ -0,0 +1,52 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.lang.reflect; | |
| 27 | + | |
| 28 | +/** | |
| 29 | + * {@code GenericArrayType} represents an array type whose component | |
| 30 | + * type is either a parameterized type or a type variable. | |
| 31 | + * @since 1.5 | |
| 32 | + */ | |
| 33 | +public interface GenericArrayType extends Type { | |
| 34 | + /** | |
| 35 | + * Returns a {@code Type} object representing the component type | |
| 36 | + * of this array. This method creates the component type of the | |
| 37 | + * array. See the declaration of {@link | |
| 38 | + * java.lang.reflect.ParameterizedType ParameterizedType} for the | |
| 39 | + * semantics of the creation process for parameterized types and | |
| 40 | + * see {@link java.lang.reflect.TypeVariable TypeVariable} for the | |
| 41 | + * creation process for type variables. | |
| 42 | + * | |
| 43 | + * @return a {@code Type} object representing the component type | |
| 44 | + * of this array | |
| 45 | + * @throws TypeNotPresentException if the underlying array type's | |
| 46 | + * component type refers to a non-existent type declaration | |
| 47 | + * @throws MalformedParameterizedTypeException if the | |
| 48 | + * underlying array type's component type refers to a | |
| 49 | + * parameterized type that cannot be instantiated for any reason | |
| 50 | + */ | |
| 51 | + Type getGenericComponentType(); | |
| 52 | +} | |
Binary file not shown.
| @@ -0,0 +1,49 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.lang.reflect; | |
| 27 | + | |
| 28 | +/** | |
| 29 | + * A common interface for all entities that declare type variables. | |
| 30 | + * | |
| 31 | + * @since 1.5 | |
| 32 | + */ | |
| 33 | +public interface GenericDeclaration { | |
| 34 | + /** | |
| 35 | + * Returns an array of {@code TypeVariable} objects that | |
| 36 | + * represent the type variables declared by the generic | |
| 37 | + * declaration represented by this {@code GenericDeclaration} | |
| 38 | + * object, in declaration order. Returns an array of length 0 if | |
| 39 | + * the underlying generic declaration declares no type variables. | |
| 40 | + * | |
| 41 | + * @return an array of {@code TypeVariable} objects that represent | |
| 42 | + * the type variables declared by this generic declaration | |
| 43 | + * @throws GenericSignatureFormatError if the generic | |
| 44 | + * signature of this generic declaration does not conform to | |
| 45 | + * the format specified in | |
| 46 | + * <cite>The Java™ Virtual Machine Specification</cite> | |
| 47 | + */ | |
| 48 | + public TypeVariable<?>[] getTypeParameters(); | |
| 49 | +} | |
Binary file not shown.
| @@ -0,0 +1,38 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.lang.reflect; | |
| 27 | + | |
| 28 | + | |
| 29 | +/** | |
| 30 | + * Thrown when a syntactically malformed signature attribute is | |
| 31 | + * encountered by a reflective method that needs to interpret the | |
| 32 | + * generic signature information for a type, method or constructor. | |
| 33 | + * | |
| 34 | + * @since 1.5 | |
| 35 | + */ | |
| 36 | +public class GenericSignatureFormatError extends ClassFormatError { | |
| 37 | + private static final long serialVersionUID = 6709919147137911034L; | |
| 38 | +} | |
Binary file not shown.
| @@ -0,0 +1,95 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 1999, 2006, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.lang.reflect; | |
| 27 | + | |
| 28 | +/** | |
| 29 | + * {@code InvocationHandler} is the interface implemented by | |
| 30 | + * the <i>invocation handler</i> of a proxy instance. | |
| 31 | + * | |
| 32 | + * <p>Each proxy instance has an associated invocation handler. | |
| 33 | + * When a method is invoked on a proxy instance, the method | |
| 34 | + * invocation is encoded and dispatched to the {@code invoke} | |
| 35 | + * method of its invocation handler. | |
| 36 | + * | |
| 37 | + * @author Peter Jones | |
| 38 | + * @see Proxy | |
| 39 | + * @since 1.3 | |
| 40 | + */ | |
| 41 | +public interface InvocationHandler { | |
| 42 | + | |
| 43 | + /** | |
| 44 | + * Processes a method invocation on a proxy instance and returns | |
| 45 | + * the result. This method will be invoked on an invocation handler | |
| 46 | + * when a method is invoked on a proxy instance that it is | |
| 47 | + * associated with. | |
| 48 | + * | |
| 49 | + * @param proxy the proxy instance that the method was invoked on | |
| 50 | + * | |
| 51 | + * @param method the {@code Method} instance corresponding to | |
| 52 | + * the interface method invoked on the proxy instance. The declaring | |
| 53 | + * class of the {@code Method} object will be the interface that | |
| 54 | + * the method was declared in, which may be a superinterface of the | |
| 55 | + * proxy interface that the proxy class inherits the method through. | |
| 56 | + * | |
| 57 | + * @param args an array of objects containing the values of the | |
| 58 | + * arguments passed in the method invocation on the proxy instance, | |
| 59 | + * or {@code null} if interface method takes no arguments. | |
| 60 | + * Arguments of primitive types are wrapped in instances of the | |
| 61 | + * appropriate primitive wrapper class, such as | |
| 62 | + * {@code java.lang.Integer} or {@code java.lang.Boolean}. | |
| 63 | + * | |
| 64 | + * @return the value to return from the method invocation on the | |
| 65 | + * proxy instance. If the declared return type of the interface | |
| 66 | + * method is a primitive type, then the value returned by | |
| 67 | + * this method must be an instance of the corresponding primitive | |
| 68 | + * wrapper class; otherwise, it must be a type assignable to the | |
| 69 | + * declared return type. If the value returned by this method is | |
| 70 | + * {@code null} and the interface method's return type is | |
| 71 | + * primitive, then a {@code NullPointerException} will be | |
| 72 | + * thrown by the method invocation on the proxy instance. If the | |
| 73 | + * value returned by this method is otherwise not compatible with | |
| 74 | + * the interface method's declared return type as described above, | |
| 75 | + * a {@code ClassCastException} will be thrown by the method | |
| 76 | + * invocation on the proxy instance. | |
| 77 | + * | |
| 78 | + * @throws Throwable the exception to throw from the method | |
| 79 | + * invocation on the proxy instance. The exception's type must be | |
| 80 | + * assignable either to any of the exception types declared in the | |
| 81 | + * {@code throws} clause of the interface method or to the | |
| 82 | + * unchecked exception types {@code java.lang.RuntimeException} | |
| 83 | + * or {@code java.lang.Error}. If a checked exception is | |
| 84 | + * thrown by this method that is not assignable to any of the | |
| 85 | + * exception types declared in the {@code throws} clause of | |
| 86 | + * the interface method, then an | |
| 87 | + * {@link UndeclaredThrowableException} containing the | |
| 88 | + * exception that was thrown by this method will be thrown by the | |
| 89 | + * method invocation on the proxy instance. | |
| 90 | + * | |
| 91 | + * @see UndeclaredThrowableException | |
| 92 | + */ | |
| 93 | + public Object invoke(Object proxy, Method method, Object[] args) | |
| 94 | + throws Throwable; | |
| 95 | +} | |
Binary file not shown.
| @@ -0,0 +1,111 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 1996, 2004, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.lang.reflect; | |
| 27 | + | |
| 28 | +/** | |
| 29 | + * InvocationTargetException is a checked exception that wraps | |
| 30 | + * an exception thrown by an invoked method or constructor. | |
| 31 | + * | |
| 32 | + * <p>As of release 1.4, this exception has been retrofitted to conform to | |
| 33 | + * the general purpose exception-chaining mechanism. The "target exception" | |
| 34 | + * that is provided at construction time and accessed via the | |
| 35 | + * {@link #getTargetException()} method is now known as the <i>cause</i>, | |
| 36 | + * and may be accessed via the {@link Throwable#getCause()} method, | |
| 37 | + * as well as the aforementioned "legacy method." | |
| 38 | + * | |
| 39 | + * @see Method | |
| 40 | + * @see Constructor | |
| 41 | + */ | |
| 42 | +public class InvocationTargetException extends ReflectiveOperationException { | |
| 43 | + /** | |
| 44 | + * Use serialVersionUID from JDK 1.1.X for interoperability | |
| 45 | + */ | |
| 46 | + private static final long serialVersionUID = 4085088731926701167L; | |
| 47 | + | |
| 48 | + /** | |
| 49 | + * This field holds the target if the | |
| 50 | + * InvocationTargetException(Throwable target) constructor was | |
| 51 | + * used to instantiate the object | |
| 52 | + * | |
| 53 | + * @serial | |
| 54 | + * | |
| 55 | + */ | |
| 56 | + private Throwable target; | |
| 57 | + | |
| 58 | + /** | |
| 59 | + * Constructs an {@code InvocationTargetException} with | |
| 60 | + * {@code null} as the target exception. | |
| 61 | + */ | |
| 62 | + protected InvocationTargetException() { | |
| 63 | + super((Throwable)null); // Disallow initCause | |
| 64 | + } | |
| 65 | + | |
| 66 | + /** | |
| 67 | + * Constructs a InvocationTargetException with a target exception. | |
| 68 | + * | |
| 69 | + * @param target the target exception | |
| 70 | + */ | |
| 71 | + public InvocationTargetException(Throwable target) { | |
| 72 | + super((Throwable)null); // Disallow initCause | |
| 73 | + this.target = target; | |
| 74 | + } | |
| 75 | + | |
| 76 | + /** | |
| 77 | + * Constructs a InvocationTargetException with a target exception | |
| 78 | + * and a detail message. | |
| 79 | + * | |
| 80 | + * @param target the target exception | |
| 81 | + * @param s the detail message | |
| 82 | + */ | |
| 83 | + public InvocationTargetException(Throwable target, String s) { | |
| 84 | + super(s, null); // Disallow initCause | |
| 85 | + this.target = target; | |
| 86 | + } | |
| 87 | + | |
| 88 | + /** | |
| 89 | + * Get the thrown target exception. | |
| 90 | + * | |
| 91 | + * <p>This method predates the general-purpose exception chaining facility. | |
| 92 | + * The {@link Throwable#getCause()} method is now the preferred means of | |
| 93 | + * obtaining this information. | |
| 94 | + * | |
| 95 | + * @return the thrown target exception (cause of this exception). | |
| 96 | + */ | |
| 97 | + public Throwable getTargetException() { | |
| 98 | + return target; | |
| 99 | + } | |
| 100 | + | |
| 101 | + /** | |
| 102 | + * Returns the cause of this exception (the thrown target exception, | |
| 103 | + * which may be {@code null}). | |
| 104 | + * | |
| 105 | + * @return the cause of this exception. | |
| 106 | + * @since 1.4 | |
| 107 | + */ | |
| 108 | + public Throwable getCause() { | |
| 109 | + return target; | |
| 110 | + } | |
| 111 | +} | |
Binary file not shown.
| @@ -0,0 +1,39 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | + | |
| 27 | +package java.lang.reflect; | |
| 28 | + | |
| 29 | +/** | |
| 30 | + * Thrown when a semantically malformed parameterized type is | |
| 31 | + * encountered by a reflective method that needs to instantiate it. | |
| 32 | + * For example, if the number of type arguments to a parameterized type | |
| 33 | + * is wrong. | |
| 34 | + * | |
| 35 | + * @since 1.5 | |
| 36 | + */ | |
| 37 | +public class MalformedParameterizedTypeException extends RuntimeException { | |
| 38 | + private static final long serialVersionUID = -5696557788586220964L; | |
| 39 | +} | |
Binary file not shown.
| @@ -0,0 +1,93 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.lang.reflect; | |
| 27 | + | |
| 28 | +/** | |
| 29 | + * Member is an interface that reflects identifying information about | |
| 30 | + * a single member (a field or a method) or a constructor. | |
| 31 | + * | |
| 32 | + * @see java.lang.Class | |
| 33 | + * @see Field | |
| 34 | + * @see Method | |
| 35 | + * @see Constructor | |
| 36 | + * | |
| 37 | + * @author Nakul Saraiya | |
| 38 | + */ | |
| 39 | +public | |
| 40 | +interface Member { | |
| 41 | + | |
| 42 | + /** | |
| 43 | + * Identifies the set of all public members of a class or interface, | |
| 44 | + * including inherited members. | |
| 45 | + * @see java.lang.SecurityManager#checkMemberAccess | |
| 46 | + */ | |
| 47 | + public static final int PUBLIC = 0; | |
| 48 | + | |
| 49 | + /** | |
| 50 | + * Identifies the set of declared members of a class or interface. | |
| 51 | + * Inherited members are not included. | |
| 52 | + * @see java.lang.SecurityManager#checkMemberAccess | |
| 53 | + */ | |
| 54 | + public static final int DECLARED = 1; | |
| 55 | + | |
| 56 | + /** | |
| 57 | + * Returns the Class object representing the class or interface | |
| 58 | + * that declares the member or constructor represented by this Member. | |
| 59 | + * | |
| 60 | + * @return an object representing the declaring class of the | |
| 61 | + * underlying member | |
| 62 | + */ | |
| 63 | + public Class<?> getDeclaringClass(); | |
| 64 | + | |
| 65 | + /** | |
| 66 | + * Returns the simple name of the underlying member or constructor | |
| 67 | + * represented by this Member. | |
| 68 | + * | |
| 69 | + * @return the simple name of the underlying member | |
| 70 | + */ | |
| 71 | + public String getName(); | |
| 72 | + | |
| 73 | + /** | |
| 74 | + * Returns the Java language modifiers for the member or | |
| 75 | + * constructor represented by this Member, as an integer. The | |
| 76 | + * Modifier class should be used to decode the modifiers in | |
| 77 | + * the integer. | |
| 78 | + * | |
| 79 | + * @return the Java language modifiers for the underlying member | |
| 80 | + * @see Modifier | |
| 81 | + */ | |
| 82 | + public int getModifiers(); | |
| 83 | + | |
| 84 | + /** | |
| 85 | + * Returns {@code true} if this member was introduced by | |
| 86 | + * the compiler; returns {@code false} otherwise. | |
| 87 | + * | |
| 88 | + * @return true if and only if this member was introduced by | |
| 89 | + * the compiler. | |
| 90 | + * @since 1.5 | |
| 91 | + */ | |
| 92 | + public boolean isSynthetic(); | |
| 93 | +} | |
Binary file not shown.
| @@ -0,0 +1,767 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.lang.reflect; | |
| 27 | + | |
| 28 | +import sun.reflect.MethodAccessor; | |
| 29 | +import sun.reflect.Reflection; | |
| 30 | +import sun.reflect.generics.repository.MethodRepository; | |
| 31 | +import sun.reflect.generics.factory.CoreReflectionFactory; | |
| 32 | +import sun.reflect.generics.factory.GenericsFactory; | |
| 33 | +import sun.reflect.generics.scope.MethodScope; | |
| 34 | +import sun.reflect.annotation.AnnotationType; | |
| 35 | +import sun.reflect.annotation.AnnotationParser; | |
| 36 | +import java.lang.annotation.Annotation; | |
| 37 | +import java.lang.annotation.AnnotationFormatError; | |
| 38 | +import java.nio.ByteBuffer; | |
| 39 | +import java.util.Map; | |
| 40 | + | |
| 41 | +/** | |
| 42 | + * A {@code Method} provides information about, and access to, a single method | |
| 43 | + * on a class or interface. The reflected method may be a class method | |
| 44 | + * or an instance method (including an abstract method). | |
| 45 | + * | |
| 46 | + * <p>A {@code Method} permits widening conversions to occur when matching the | |
| 47 | + * actual parameters to invoke with the underlying method's formal | |
| 48 | + * parameters, but it throws an {@code IllegalArgumentException} if a | |
| 49 | + * narrowing conversion would occur. | |
| 50 | + * | |
| 51 | + * @see Member | |
| 52 | + * @see java.lang.Class | |
| 53 | + * @see java.lang.Class#getMethods() | |
| 54 | + * @see java.lang.Class#getMethod(String, Class[]) | |
| 55 | + * @see java.lang.Class#getDeclaredMethods() | |
| 56 | + * @see java.lang.Class#getDeclaredMethod(String, Class[]) | |
| 57 | + * | |
| 58 | + * @author Kenneth Russell | |
| 59 | + * @author Nakul Saraiya | |
| 60 | + */ | |
| 61 | +public final | |
| 62 | + class Method extends AccessibleObject implements GenericDeclaration, | |
| 63 | + Member { | |
| 64 | + private Class<?> clazz; | |
| 65 | + private int slot; | |
| 66 | + // This is guaranteed to be interned by the VM in the 1.4 | |
| 67 | + // reflection implementation | |
| 68 | + private String name; | |
| 69 | + private Class<?> returnType; | |
| 70 | + private Class<?>[] parameterTypes; | |
| 71 | + private Class<?>[] exceptionTypes; | |
| 72 | + private int modifiers; | |
| 73 | + // Generics and annotations support | |
| 74 | + private transient String signature; | |
| 75 | + // generic info repository; lazily initialized | |
| 76 | + private transient MethodRepository genericInfo; | |
| 77 | + private byte[] annotations; | |
| 78 | + private byte[] parameterAnnotations; | |
| 79 | + private byte[] annotationDefault; | |
| 80 | + private volatile MethodAccessor methodAccessor; | |
| 81 | + // For sharing of MethodAccessors. This branching structure is | |
| 82 | + // currently only two levels deep (i.e., one root Method and | |
| 83 | + // potentially many Method objects pointing to it.) | |
| 84 | + private Method root; | |
| 85 | + | |
| 86 | + // Generics infrastructure | |
| 87 | + | |
| 88 | + private String getGenericSignature() {return signature;} | |
| 89 | + | |
| 90 | + // Accessor for factory | |
| 91 | + private GenericsFactory getFactory() { | |
| 92 | + // create scope and factory | |
| 93 | + return CoreReflectionFactory.make(this, MethodScope.make(this)); | |
| 94 | + } | |
| 95 | + | |
| 96 | + // Accessor for generic info repository | |
| 97 | + private MethodRepository getGenericInfo() { | |
| 98 | + // lazily initialize repository if necessary | |
| 99 | + if (genericInfo == null) { | |
| 100 | + // create and cache generic info repository | |
| 101 | + genericInfo = MethodRepository.make(getGenericSignature(), | |
| 102 | + getFactory()); | |
| 103 | + } | |
| 104 | + return genericInfo; //return cached repository | |
| 105 | + } | |
| 106 | + | |
| 107 | + /** | |
| 108 | + * Package-private constructor used by ReflectAccess to enable | |
| 109 | + * instantiation of these objects in Java code from the java.lang | |
| 110 | + * package via sun.reflect.LangReflectAccess. | |
| 111 | + */ | |
| 112 | + Method(Class<?> declaringClass, | |
| 113 | + String name, | |
| 114 | + Class<?>[] parameterTypes, | |
| 115 | + Class<?> returnType, | |
| 116 | + Class<?>[] checkedExceptions, | |
| 117 | + int modifiers, | |
| 118 | + int slot, | |
| 119 | + String signature, | |
| 120 | + byte[] annotations, | |
| 121 | + byte[] parameterAnnotations, | |
| 122 | + byte[] annotationDefault) | |
| 123 | + { | |
| 124 | + this.clazz = declaringClass; | |
| 125 | + this.name = name; | |
| 126 | + this.parameterTypes = parameterTypes; | |
| 127 | + this.returnType = returnType; | |
| 128 | + this.exceptionTypes = checkedExceptions; | |
| 129 | + this.modifiers = modifiers; | |
| 130 | + this.slot = slot; | |
| 131 | + this.signature = signature; | |
| 132 | + this.annotations = annotations; | |
| 133 | + this.parameterAnnotations = parameterAnnotations; | |
| 134 | + this.annotationDefault = annotationDefault; | |
| 135 | + } | |
| 136 | + | |
| 137 | + /** | |
| 138 | + * Package-private routine (exposed to java.lang.Class via | |
| 139 | + * ReflectAccess) which returns a copy of this Method. The copy's | |
| 140 | + * "root" field points to this Method. | |
| 141 | + */ | |
| 142 | + Method copy() { | |
| 143 | + // This routine enables sharing of MethodAccessor objects | |
| 144 | + // among Method objects which refer to the same underlying | |
| 145 | + // method in the VM. (All of this contortion is only necessary | |
| 146 | + // because of the "accessibility" bit in AccessibleObject, | |
| 147 | + // which implicitly requires that new java.lang.reflect | |
| 148 | + // objects be fabricated for each reflective call on Class | |
| 149 | + // objects.) | |
| 150 | + Method res = new Method(clazz, name, parameterTypes, returnType, | |
| 151 | + exceptionTypes, modifiers, slot, signature, | |
| 152 | + annotations, parameterAnnotations, annotationDefault); | |
| 153 | + res.root = this; | |
| 154 | + // Might as well eagerly propagate this if already present | |
| 155 | + res.methodAccessor = methodAccessor; | |
| 156 | + return res; | |
| 157 | + } | |
| 158 | + | |
| 159 | + /** | |
| 160 | + * Returns the {@code Class} object representing the class or interface | |
| 161 | + * that declares the method represented by this {@code Method} object. | |
| 162 | + */ | |
| 163 | + public Class<?> getDeclaringClass() { | |
| 164 | + return clazz; | |
| 165 | + } | |
| 166 | + | |
| 167 | + /** | |
| 168 | + * Returns the name of the method represented by this {@code Method} | |
| 169 | + * object, as a {@code String}. | |
| 170 | + */ | |
| 171 | + public String getName() { | |
| 172 | + return name; | |
| 173 | + } | |
| 174 | + | |
| 175 | + /** | |
| 176 | + * Returns the Java language modifiers for the method represented | |
| 177 | + * by this {@code Method} object, as an integer. The {@code Modifier} class should | |
| 178 | + * be used to decode the modifiers. | |
| 179 | + * | |
| 180 | + * @see Modifier | |
| 181 | + */ | |
| 182 | + public int getModifiers() { | |
| 183 | + return modifiers; | |
| 184 | + } | |
| 185 | + | |
| 186 | + /** | |
| 187 | + * Returns an array of {@code TypeVariable} objects that represent the | |
| 188 | + * type variables declared by the generic declaration represented by this | |
| 189 | + * {@code GenericDeclaration} object, in declaration order. Returns an | |
| 190 | + * array of length 0 if the underlying generic declaration declares no type | |
| 191 | + * variables. | |
| 192 | + * | |
| 193 | + * @return an array of {@code TypeVariable} objects that represent | |
| 194 | + * the type variables declared by this generic declaration | |
| 195 | + * @throws GenericSignatureFormatError if the generic | |
| 196 | + * signature of this generic declaration does not conform to | |
| 197 | + * the format specified in | |
| 198 | + * <cite>The Java™ Virtual Machine Specification</cite> | |
| 199 | + * @since 1.5 | |
| 200 | + */ | |
| 201 | + public TypeVariable<Method>[] getTypeParameters() { | |
| 202 | + if (getGenericSignature() != null) | |
| 203 | + return (TypeVariable<Method>[])getGenericInfo().getTypeParameters(); | |
| 204 | + else | |
| 205 | + return (TypeVariable<Method>[])new TypeVariable[0]; | |
| 206 | + } | |
| 207 | + | |
| 208 | + /** | |
| 209 | + * Returns a {@code Class} object that represents the formal return type | |
| 210 | + * of the method represented by this {@code Method} object. | |
| 211 | + * | |
| 212 | + * @return the return type for the method this object represents | |
| 213 | + */ | |
| 214 | + public Class<?> getReturnType() { | |
| 215 | + return returnType; | |
| 216 | + } | |
| 217 | + | |
| 218 | + /** | |
| 219 | + * Returns a {@code Type} object that represents the formal return | |
| 220 | + * type of the method represented by this {@code Method} object. | |
| 221 | + * | |
| 222 | + * <p>If the return type is a parameterized type, | |
| 223 | + * the {@code Type} object returned must accurately reflect | |
| 224 | + * the actual type parameters used in the source code. | |
| 225 | + * | |
| 226 | + * <p>If the return type is a type variable or a parameterized type, it | |
| 227 | + * is created. Otherwise, it is resolved. | |
| 228 | + * | |
| 229 | + * @return a {@code Type} object that represents the formal return | |
| 230 | + * type of the underlying method | |
| 231 | + * @throws GenericSignatureFormatError | |
| 232 | + * if the generic method signature does not conform to the format | |
| 233 | + * specified in | |
| 234 | + * <cite>The Java™ Virtual Machine Specification</cite> | |
| 235 | + * @throws TypeNotPresentException if the underlying method's | |
| 236 | + * return type refers to a non-existent type declaration | |
| 237 | + * @throws MalformedParameterizedTypeException if the | |
| 238 | + * underlying method's return typed refers to a parameterized | |
| 239 | + * type that cannot be instantiated for any reason | |
| 240 | + * @since 1.5 | |
| 241 | + */ | |
| 242 | + public Type getGenericReturnType() { | |
| 243 | + if (getGenericSignature() != null) { | |
| 244 | + return getGenericInfo().getReturnType(); | |
| 245 | + } else { return getReturnType();} | |
| 246 | + } | |
| 247 | + | |
| 248 | + | |
| 249 | + /** | |
| 250 | + * Returns an array of {@code Class} objects that represent the formal | |
| 251 | + * parameter types, in declaration order, of the method | |
| 252 | + * represented by this {@code Method} object. Returns an array of length | |
| 253 | + * 0 if the underlying method takes no parameters. | |
| 254 | + * | |
| 255 | + * @return the parameter types for the method this object | |
| 256 | + * represents | |
| 257 | + */ | |
| 258 | + public Class<?>[] getParameterTypes() { | |
| 259 | + return (Class<?>[]) parameterTypes.clone(); | |
| 260 | + } | |
| 261 | + | |
| 262 | + /** | |
| 263 | + * Returns an array of {@code Type} objects that represent the formal | |
| 264 | + * parameter types, in declaration order, of the method represented by | |
| 265 | + * this {@code Method} object. Returns an array of length 0 if the | |
| 266 | + * underlying method takes no parameters. | |
| 267 | + * | |
| 268 | + * <p>If a formal parameter type is a parameterized type, | |
| 269 | + * the {@code Type} object returned for it must accurately reflect | |
| 270 | + * the actual type parameters used in the source code. | |
| 271 | + * | |
| 272 | + * <p>If a formal parameter type is a type variable or a parameterized | |
| 273 | + * type, it is created. Otherwise, it is resolved. | |
| 274 | + * | |
| 275 | + * @return an array of Types that represent the formal | |
| 276 | + * parameter types of the underlying method, in declaration order | |
| 277 | + * @throws GenericSignatureFormatError | |
| 278 | + * if the generic method signature does not conform to the format | |
| 279 | + * specified in | |
| 280 | + * <cite>The Java™ Virtual Machine Specification</cite> | |
| 281 | + * @throws TypeNotPresentException if any of the parameter | |
| 282 | + * types of the underlying method refers to a non-existent type | |
| 283 | + * declaration | |
| 284 | + * @throws MalformedParameterizedTypeException if any of | |
| 285 | + * the underlying method's parameter types refer to a parameterized | |
| 286 | + * type that cannot be instantiated for any reason | |
| 287 | + * @since 1.5 | |
| 288 | + */ | |
| 289 | + public Type[] getGenericParameterTypes() { | |
| 290 | + if (getGenericSignature() != null) | |
| 291 | + return getGenericInfo().getParameterTypes(); | |
| 292 | + else | |
| 293 | + return getParameterTypes(); | |
| 294 | + } | |
| 295 | + | |
| 296 | + | |
| 297 | + /** | |
| 298 | + * Returns an array of {@code Class} objects that represent | |
| 299 | + * the types of the exceptions declared to be thrown | |
| 300 | + * by the underlying method | |
| 301 | + * represented by this {@code Method} object. Returns an array of length | |
| 302 | + * 0 if the method declares no exceptions in its {@code throws} clause. | |
| 303 | + * | |
| 304 | + * @return the exception types declared as being thrown by the | |
| 305 | + * method this object represents | |
| 306 | + */ | |
| 307 | + public Class<?>[] getExceptionTypes() { | |
| 308 | + return (Class<?>[]) exceptionTypes.clone(); | |
| 309 | + } | |
| 310 | + | |
| 311 | + /** | |
| 312 | + * Returns an array of {@code Type} objects that represent the | |
| 313 | + * exceptions declared to be thrown by this {@code Method} object. | |
| 314 | + * Returns an array of length 0 if the underlying method declares | |
| 315 | + * no exceptions in its {@code throws} clause. | |
| 316 | + * | |
| 317 | + * <p>If an exception type is a type variable or a parameterized | |
| 318 | + * type, it is created. Otherwise, it is resolved. | |
| 319 | + * | |
| 320 | + * @return an array of Types that represent the exception types | |
| 321 | + * thrown by the underlying method | |
| 322 | + * @throws GenericSignatureFormatError | |
| 323 | + * if the generic method signature does not conform to the format | |
| 324 | + * specified in | |
| 325 | + * <cite>The Java™ Virtual Machine Specification</cite> | |
| 326 | + * @throws TypeNotPresentException if the underlying method's | |
| 327 | + * {@code throws} clause refers to a non-existent type declaration | |
| 328 | + * @throws MalformedParameterizedTypeException if | |
| 329 | + * the underlying method's {@code throws} clause refers to a | |
| 330 | + * parameterized type that cannot be instantiated for any reason | |
| 331 | + * @since 1.5 | |
| 332 | + */ | |
| 333 | + public Type[] getGenericExceptionTypes() { | |
| 334 | + Type[] result; | |
| 335 | + if (getGenericSignature() != null && | |
| 336 | + ((result = getGenericInfo().getExceptionTypes()).length > 0)) | |
| 337 | + return result; | |
| 338 | + else | |
| 339 | + return getExceptionTypes(); | |
| 340 | + } | |
| 341 | + | |
| 342 | + /** | |
| 343 | + * Compares this {@code Method} against the specified object. Returns | |
| 344 | + * true if the objects are the same. Two {@code Methods} are the same if | |
| 345 | + * they were declared by the same class and have the same name | |
| 346 | + * and formal parameter types and return type. | |
| 347 | + */ | |
| 348 | + public boolean equals(Object obj) { | |
| 349 | + if (obj != null && obj instanceof Method) { | |
| 350 | + Method other = (Method)obj; | |
| 351 | + if ((getDeclaringClass() == other.getDeclaringClass()) | |
| 352 | + && (getName() == other.getName())) { | |
| 353 | + if (!returnType.equals(other.getReturnType())) | |
| 354 | + return false; | |
| 355 | + /* Avoid unnecessary cloning */ | |
| 356 | + Class<?>[] params1 = parameterTypes; | |
| 357 | + Class<?>[] params2 = other.parameterTypes; | |
| 358 | + if (params1.length == params2.length) { | |
| 359 | + for (int i = 0; i < params1.length; i++) { | |
| 360 | + if (params1[i] != params2[i]) | |
| 361 | + return false; | |
| 362 | + } | |
| 363 | + return true; | |
| 364 | + } | |
| 365 | + } | |
| 366 | + } | |
| 367 | + return false; | |
| 368 | + } | |
| 369 | + | |
| 370 | + /** | |
| 371 | + * Returns a hashcode for this {@code Method}. The hashcode is computed | |
| 372 | + * as the exclusive-or of the hashcodes for the underlying | |
| 373 | + * method's declaring class name and the method's name. | |
| 374 | + */ | |
| 375 | + public int hashCode() { | |
| 376 | + return getDeclaringClass().getName().hashCode() ^ getName().hashCode(); | |
| 377 | + } | |
| 378 | + | |
| 379 | + /** | |
| 380 | + * Returns a string describing this {@code Method}. The string is | |
| 381 | + * formatted as the method access modifiers, if any, followed by | |
| 382 | + * the method return type, followed by a space, followed by the | |
| 383 | + * class declaring the method, followed by a period, followed by | |
| 384 | + * the method name, followed by a parenthesized, comma-separated | |
| 385 | + * list of the method's formal parameter types. If the method | |
| 386 | + * throws checked exceptions, the parameter list is followed by a | |
| 387 | + * space, followed by the word throws followed by a | |
| 388 | + * comma-separated list of the thrown exception types. | |
| 389 | + * For example: | |
| 390 | + * <pre> | |
| 391 | + * public boolean java.lang.Object.equals(java.lang.Object) | |
| 392 | + * </pre> | |
| 393 | + * | |
| 394 | + * <p>The access modifiers are placed in canonical order as | |
| 395 | + * specified by "The Java Language Specification". This is | |
| 396 | + * {@code public}, {@code protected} or {@code private} first, | |
| 397 | + * and then other modifiers in the following order: | |
| 398 | + * {@code abstract}, {@code static}, {@code final}, | |
| 399 | + * {@code synchronized}, {@code native}, {@code strictfp}. | |
| 400 | + */ | |
| 401 | + public String toString() { | |
| 402 | + try { | |
| 403 | + StringBuilder sb = new StringBuilder(); | |
| 404 | + int mod = getModifiers() & Modifier.methodModifiers(); | |
| 405 | + if (mod != 0) { | |
| 406 | + sb.append(Modifier.toString(mod)).append(' '); | |
| 407 | + } | |
| 408 | + sb.append(Field.getTypeName(getReturnType())).append(' '); | |
| 409 | + sb.append(Field.getTypeName(getDeclaringClass())).append('.'); | |
| 410 | + sb.append(getName()).append('('); | |
| 411 | + Class<?>[] params = parameterTypes; // avoid clone | |
| 412 | + for (int j = 0; j < params.length; j++) { | |
| 413 | + sb.append(Field.getTypeName(params[j])); | |
| 414 | + if (j < (params.length - 1)) | |
| 415 | + sb.append(','); | |
| 416 | + } | |
| 417 | + sb.append(')'); | |
| 418 | + Class<?>[] exceptions = exceptionTypes; // avoid clone | |
| 419 | + if (exceptions.length > 0) { | |
| 420 | + sb.append(" throws "); | |
| 421 | + for (int k = 0; k < exceptions.length; k++) { | |
| 422 | + sb.append(exceptions[k].getName()); | |
| 423 | + if (k < (exceptions.length - 1)) | |
| 424 | + sb.append(','); | |
| 425 | + } | |
| 426 | + } | |
| 427 | + return sb.toString(); | |
| 428 | + } catch (Exception e) { | |
| 429 | + return "<" + e + ">"; | |
| 430 | + } | |
| 431 | + } | |
| 432 | + | |
| 433 | + /** | |
| 434 | + * Returns a string describing this {@code Method}, including | |
| 435 | + * type parameters. The string is formatted as the method access | |
| 436 | + * modifiers, if any, followed by an angle-bracketed | |
| 437 | + * comma-separated list of the method's type parameters, if any, | |
| 438 | + * followed by the method's generic return type, followed by a | |
| 439 | + * space, followed by the class declaring the method, followed by | |
| 440 | + * a period, followed by the method name, followed by a | |
| 441 | + * parenthesized, comma-separated list of the method's generic | |
| 442 | + * formal parameter types. | |
| 443 | + * | |
| 444 | + * If this method was declared to take a variable number of | |
| 445 | + * arguments, instead of denoting the last parameter as | |
| 446 | + * "<tt><i>Type</i>[]</tt>", it is denoted as | |
| 447 | + * "<tt><i>Type</i>...</tt>". | |
| 448 | + * | |
| 449 | + * A space is used to separate access modifiers from one another | |
| 450 | + * and from the type parameters or return type. If there are no | |
| 451 | + * type parameters, the type parameter list is elided; if the type | |
| 452 | + * parameter list is present, a space separates the list from the | |
| 453 | + * class name. If the method is declared to throw exceptions, the | |
| 454 | + * parameter list is followed by a space, followed by the word | |
| 455 | + * throws followed by a comma-separated list of the generic thrown | |
| 456 | + * exception types. If there are no type parameters, the type | |
| 457 | + * parameter list is elided. | |
| 458 | + * | |
| 459 | + * <p>The access modifiers are placed in canonical order as | |
| 460 | + * specified by "The Java Language Specification". This is | |
| 461 | + * {@code public}, {@code protected} or {@code private} first, | |
| 462 | + * and then other modifiers in the following order: | |
| 463 | + * {@code abstract}, {@code static}, {@code final}, | |
| 464 | + * {@code synchronized}, {@code native}, {@code strictfp}. | |
| 465 | + * | |
| 466 | + * @return a string describing this {@code Method}, | |
| 467 | + * include type parameters | |
| 468 | + * | |
| 469 | + * @since 1.5 | |
| 470 | + */ | |
| 471 | + public String toGenericString() { | |
| 472 | + try { | |
| 473 | + StringBuilder sb = new StringBuilder(); | |
| 474 | + int mod = getModifiers() & Modifier.methodModifiers(); | |
| 475 | + if (mod != 0) { | |
| 476 | + sb.append(Modifier.toString(mod)).append(' '); | |
| 477 | + } | |
| 478 | + TypeVariable<?>[] typeparms = getTypeParameters(); | |
| 479 | + if (typeparms.length > 0) { | |
| 480 | + boolean first = true; | |
| 481 | + sb.append('<'); | |
| 482 | + for(TypeVariable<?> typeparm: typeparms) { | |
| 483 | + if (!first) | |
| 484 | + sb.append(','); | |
| 485 | + // Class objects can't occur here; no need to test | |
| 486 | + // and call Class.getName(). | |
| 487 | + sb.append(typeparm.toString()); | |
| 488 | + first = false; | |
| 489 | + } | |
| 490 | + sb.append("> "); | |
| 491 | + } | |
| 492 | + | |
| 493 | + Type genRetType = getGenericReturnType(); | |
| 494 | + sb.append( ((genRetType instanceof Class<?>)? | |
| 495 | + Field.getTypeName((Class<?>)genRetType):genRetType.toString())) | |
| 496 | + .append(' '); | |
| 497 | + | |
| 498 | + sb.append(Field.getTypeName(getDeclaringClass())).append('.'); | |
| 499 | + sb.append(getName()).append('('); | |
| 500 | + Type[] params = getGenericParameterTypes(); | |
| 501 | + for (int j = 0; j < params.length; j++) { | |
| 502 | + String param = (params[j] instanceof Class)? | |
| 503 | + Field.getTypeName((Class)params[j]): | |
| 504 | + (params[j].toString()); | |
| 505 | + if (isVarArgs() && (j == params.length - 1)) // replace T[] with T... | |
| 506 | + param = param.replaceFirst("\\[\\]$", "..."); | |
| 507 | + sb.append(param); | |
| 508 | + if (j < (params.length - 1)) | |
| 509 | + sb.append(','); | |
| 510 | + } | |
| 511 | + sb.append(')'); | |
| 512 | + Type[] exceptions = getGenericExceptionTypes(); | |
| 513 | + if (exceptions.length > 0) { | |
| 514 | + sb.append(" throws "); | |
| 515 | + for (int k = 0; k < exceptions.length; k++) { | |
| 516 | + sb.append((exceptions[k] instanceof Class)? | |
| 517 | + ((Class)exceptions[k]).getName(): | |
| 518 | + exceptions[k].toString()); | |
| 519 | + if (k < (exceptions.length - 1)) | |
| 520 | + sb.append(','); | |
| 521 | + } | |
| 522 | + } | |
| 523 | + return sb.toString(); | |
| 524 | + } catch (Exception e) { | |
| 525 | + return "<" + e + ">"; | |
| 526 | + } | |
| 527 | + } | |
| 528 | + | |
| 529 | + /** | |
| 530 | + * Invokes the underlying method represented by this {@code Method} | |
| 531 | + * object, on the specified object with the specified parameters. | |
| 532 | + * Individual parameters are automatically unwrapped to match | |
| 533 | + * primitive formal parameters, and both primitive and reference | |
| 534 | + * parameters are subject to method invocation conversions as | |
| 535 | + * necessary. | |
| 536 | + * | |
| 537 | + * <p>If the underlying method is static, then the specified {@code obj} | |
| 538 | + * argument is ignored. It may be null. | |
| 539 | + * | |
| 540 | + * <p>If the number of formal parameters required by the underlying method is | |
| 541 | + * 0, the supplied {@code args} array may be of length 0 or null. | |
| 542 | + * | |
| 543 | + * <p>If the underlying method is an instance method, it is invoked | |
| 544 | + * using dynamic method lookup as documented in The Java Language | |
| 545 | + * Specification, Second Edition, section 15.12.4.4; in particular, | |
| 546 | + * overriding based on the runtime type of the target object will occur. | |
| 547 | + * | |
| 548 | + * <p>If the underlying method is static, the class that declared | |
| 549 | + * the method is initialized if it has not already been initialized. | |
| 550 | + * | |
| 551 | + * <p>If the method completes normally, the value it returns is | |
| 552 | + * returned to the caller of invoke; if the value has a primitive | |
| 553 | + * type, it is first appropriately wrapped in an object. However, | |
| 554 | + * if the value has the type of an array of a primitive type, the | |
| 555 | + * elements of the array are <i>not</i> wrapped in objects; in | |
| 556 | + * other words, an array of primitive type is returned. If the | |
| 557 | + * underlying method return type is void, the invocation returns | |
| 558 | + * null. | |
| 559 | + * | |
| 560 | + * @param obj the object the underlying method is invoked from | |
| 561 | + * @param args the arguments used for the method call | |
| 562 | + * @return the result of dispatching the method represented by | |
| 563 | + * this object on {@code obj} with parameters | |
| 564 | + * {@code args} | |
| 565 | + * | |
| 566 | + * @exception IllegalAccessException if this {@code Method} object | |
| 567 | + * is enforcing Java language access control and the underlying | |
| 568 | + * method is inaccessible. | |
| 569 | + * @exception IllegalArgumentException if the method is an | |
| 570 | + * instance method and the specified object argument | |
| 571 | + * is not an instance of the class or interface | |
| 572 | + * declaring the underlying method (or of a subclass | |
| 573 | + * or implementor thereof); if the number of actual | |
| 574 | + * and formal parameters differ; if an unwrapping | |
| 575 | + * conversion for primitive arguments fails; or if, | |
| 576 | + * after possible unwrapping, a parameter value | |
| 577 | + * cannot be converted to the corresponding formal | |
| 578 | + * parameter type by a method invocation conversion. | |
| 579 | + * @exception InvocationTargetException if the underlying method | |
| 580 | + * throws an exception. | |
| 581 | + * @exception NullPointerException if the specified object is null | |
| 582 | + * and the method is an instance method. | |
| 583 | + * @exception ExceptionInInitializerError if the initialization | |
| 584 | + * provoked by this method fails. | |
| 585 | + */ | |
| 586 | + public Object invoke(Object obj, Object... args) | |
| 587 | + throws IllegalAccessException, IllegalArgumentException, | |
| 588 | + InvocationTargetException | |
| 589 | + { | |
| 590 | + if (!override) { | |
| 591 | + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { | |
| 592 | + Class<?> caller = Reflection.getCallerClass(1); | |
| 593 | + | |
| 594 | + checkAccess(caller, clazz, obj, modifiers); | |
| 595 | + } | |
| 596 | + } | |
| 597 | + MethodAccessor ma = methodAccessor; // read volatile | |
| 598 | + if (ma == null) { | |
| 599 | + ma = acquireMethodAccessor(); | |
| 600 | + } | |
| 601 | + return ma.invoke(obj, args); | |
| 602 | + } | |
| 603 | + | |
| 604 | + /** | |
| 605 | + * Returns {@code true} if this method is a bridge | |
| 606 | + * method; returns {@code false} otherwise. | |
| 607 | + * | |
| 608 | + * @return true if and only if this method is a bridge | |
| 609 | + * method as defined by the Java Language Specification. | |
| 610 | + * @since 1.5 | |
| 611 | + */ | |
| 612 | + public boolean isBridge() { | |
| 613 | + return (getModifiers() & Modifier.BRIDGE) != 0; | |
| 614 | + } | |
| 615 | + | |
| 616 | + /** | |
| 617 | + * Returns {@code true} if this method was declared to take | |
| 618 | + * a variable number of arguments; returns {@code false} | |
| 619 | + * otherwise. | |
| 620 | + * | |
| 621 | + * @return {@code true} if an only if this method was declared to | |
| 622 | + * take a variable number of arguments. | |
| 623 | + * @since 1.5 | |
| 624 | + */ | |
| 625 | + public boolean isVarArgs() { | |
| 626 | + return (getModifiers() & Modifier.VARARGS) != 0; | |
| 627 | + } | |
| 628 | + | |
| 629 | + /** | |
| 630 | + * Returns {@code true} if this method is a synthetic | |
| 631 | + * method; returns {@code false} otherwise. | |
| 632 | + * | |
| 633 | + * @return true if and only if this method is a synthetic | |
| 634 | + * method as defined by the Java Language Specification. | |
| 635 | + * @since 1.5 | |
| 636 | + */ | |
| 637 | + public boolean isSynthetic() { | |
| 638 | + return Modifier.isSynthetic(getModifiers()); | |
| 639 | + } | |
| 640 | + | |
| 641 | + // NOTE that there is no synchronization used here. It is correct | |
| 642 | + // (though not efficient) to generate more than one MethodAccessor | |
| 643 | + // for a given Method. However, avoiding synchronization will | |
| 644 | + // probably make the implementation more scalable. | |
| 645 | + private MethodAccessor acquireMethodAccessor() { | |
| 646 | + // First check to see if one has been created yet, and take it | |
| 647 | + // if so | |
| 648 | + MethodAccessor tmp = null; | |
| 649 | + if (root != null) tmp = root.getMethodAccessor(); | |
| 650 | + if (tmp != null) { | |
| 651 | + methodAccessor = tmp; | |
| 652 | + } else { | |
| 653 | + // Otherwise fabricate one and propagate it up to the root | |
| 654 | + tmp = reflectionFactory.newMethodAccessor(this); | |
| 655 | + setMethodAccessor(tmp); | |
| 656 | + } | |
| 657 | + | |
| 658 | + return tmp; | |
| 659 | + } | |
| 660 | + | |
| 661 | + // Returns MethodAccessor for this Method object, not looking up | |
| 662 | + // the chain to the root | |
| 663 | + MethodAccessor getMethodAccessor() { | |
| 664 | + return methodAccessor; | |
| 665 | + } | |
| 666 | + | |
| 667 | + // Sets the MethodAccessor for this Method object and | |
| 668 | + // (recursively) its root | |
| 669 | + void setMethodAccessor(MethodAccessor accessor) { | |
| 670 | + methodAccessor = accessor; | |
| 671 | + // Propagate up | |
| 672 | + if (root != null) { | |
| 673 | + root.setMethodAccessor(accessor); | |
| 674 | + } | |
| 675 | + } | |
| 676 | + | |
| 677 | + /** | |
| 678 | + * @throws NullPointerException {@inheritDoc} | |
| 679 | + * @since 1.5 | |
| 680 | + */ | |
| 681 | + public <T extends Annotation> T getAnnotation(Class<T> annotationClass) { | |
| 682 | + if (annotationClass == null) | |
| 683 | + throw new NullPointerException(); | |
| 684 | + | |
| 685 | + return (T) declaredAnnotations().get(annotationClass); | |
| 686 | + } | |
| 687 | + | |
| 688 | + /** | |
| 689 | + * @since 1.5 | |
| 690 | + */ | |
| 691 | + public Annotation[] getDeclaredAnnotations() { | |
| 692 | + return AnnotationParser.toArray(declaredAnnotations()); | |
| 693 | + } | |
| 694 | + | |
| 695 | + private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations; | |
| 696 | + | |
| 697 | + private synchronized Map<Class<? extends Annotation>, Annotation> declaredAnnotations() { | |
| 698 | + if (declaredAnnotations == null) { | |
| 699 | + declaredAnnotations = AnnotationParser.parseAnnotations( | |
| 700 | + annotations, sun.misc.SharedSecrets.getJavaLangAccess(). | |
| 701 | + getConstantPool(getDeclaringClass()), | |
| 702 | + getDeclaringClass()); | |
| 703 | + } | |
| 704 | + return declaredAnnotations; | |
| 705 | + } | |
| 706 | + | |
| 707 | + /** | |
| 708 | + * Returns the default value for the annotation member represented by | |
| 709 | + * this {@code Method} instance. If the member is of a primitive type, | |
| 710 | + * an instance of the corresponding wrapper type is returned. Returns | |
| 711 | + * null if no default is associated with the member, or if the method | |
| 712 | + * instance does not represent a declared member of an annotation type. | |
| 713 | + * | |
| 714 | + * @return the default value for the annotation member represented | |
| 715 | + * by this {@code Method} instance. | |
| 716 | + * @throws TypeNotPresentException if the annotation is of type | |
| 717 | + * {@link Class} and no definition can be found for the | |
| 718 | + * default class value. | |
| 719 | + * @since 1.5 | |
| 720 | + */ | |
| 721 | + public Object getDefaultValue() { | |
| 722 | + if (annotationDefault == null) | |
| 723 | + return null; | |
| 724 | + Class<?> memberType = AnnotationType.invocationHandlerReturnType( | |
| 725 | + getReturnType()); | |
| 726 | + Object result = AnnotationParser.parseMemberValue( | |
| 727 | + memberType, ByteBuffer.wrap(annotationDefault), | |
| 728 | + sun.misc.SharedSecrets.getJavaLangAccess(). | |
| 729 | + getConstantPool(getDeclaringClass()), | |
| 730 | + getDeclaringClass()); | |
| 731 | + if (result instanceof sun.reflect.annotation.ExceptionProxy) | |
| 732 | + throw new AnnotationFormatError("Invalid default: " + this); | |
| 733 | + return result; | |
| 734 | + } | |
| 735 | + | |
| 736 | + /** | |
| 737 | + * Returns an array of arrays that represent the annotations on the formal | |
| 738 | + * parameters, in declaration order, of the method represented by | |
| 739 | + * this {@code Method} object. (Returns an array of length zero if the | |
| 740 | + * underlying method is parameterless. If the method has one or more | |
| 741 | + * parameters, a nested array of length zero is returned for each parameter | |
| 742 | + * with no annotations.) The annotation objects contained in the returned | |
| 743 | + * arrays are serializable. The caller of this method is free to modify | |
| 744 | + * the returned arrays; it will have no effect on the arrays returned to | |
| 745 | + * other callers. | |
| 746 | + * | |
| 747 | + * @return an array of arrays that represent the annotations on the formal | |
| 748 | + * parameters, in declaration order, of the method represented by this | |
| 749 | + * Method object | |
| 750 | + * @since 1.5 | |
| 751 | + */ | |
| 752 | + public Annotation[][] getParameterAnnotations() { | |
| 753 | + int numParameters = parameterTypes.length; | |
| 754 | + if (parameterAnnotations == null) | |
| 755 | + return new Annotation[numParameters][0]; | |
| 756 | + | |
| 757 | + Annotation[][] result = AnnotationParser.parseParameterAnnotations( | |
| 758 | + parameterAnnotations, | |
| 759 | + sun.misc.SharedSecrets.getJavaLangAccess(). | |
| 760 | + getConstantPool(getDeclaringClass()), | |
| 761 | + getDeclaringClass()); | |
| 762 | + if (result.length != numParameters) | |
| 763 | + throw new java.lang.annotation.AnnotationFormatError( | |
| 764 | + "Parameter annotations don't match number of parameters"); | |
| 765 | + return result; | |
| 766 | + } | |
| 767 | +} | |
Binary file not shown.
| @@ -0,0 +1,452 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.lang.reflect; | |
| 27 | + | |
| 28 | +import java.security.AccessController; | |
| 29 | +import sun.reflect.LangReflectAccess; | |
| 30 | +import sun.reflect.ReflectionFactory; | |
| 31 | + | |
| 32 | +/** | |
| 33 | + * The Modifier class provides {@code static} methods and | |
| 34 | + * constants to decode class and member access modifiers. The sets of | |
| 35 | + * modifiers are represented as integers with distinct bit positions | |
| 36 | + * representing different modifiers. The values for the constants | |
| 37 | + * representing the modifiers are taken from the tables in sections 4.1, 4.4, 4.5, and 4.7 of | |
| 38 | + * <cite>The Java™ Virtual Machine Specification</cite>. | |
| 39 | + * | |
| 40 | + * @see Class#getModifiers() | |
| 41 | + * @see Member#getModifiers() | |
| 42 | + * | |
| 43 | + * @author Nakul Saraiya | |
| 44 | + * @author Kenneth Russell | |
| 45 | + */ | |
| 46 | +public | |
| 47 | +class Modifier { | |
| 48 | + | |
| 49 | + /* | |
| 50 | + * Bootstrapping protocol between java.lang and java.lang.reflect | |
| 51 | + * packages | |
| 52 | + */ | |
| 53 | + static { | |
| 54 | + sun.reflect.ReflectionFactory factory = | |
| 55 | + AccessController.doPrivileged( | |
| 56 | + new ReflectionFactory.GetReflectionFactoryAction()); | |
| 57 | + factory.setLangReflectAccess(new java.lang.reflect.ReflectAccess()); | |
| 58 | + } | |
| 59 | + | |
| 60 | + /** | |
| 61 | + * Return {@code true} if the integer argument includes the | |
| 62 | + * {@code public} modifier, {@code false} otherwise. | |
| 63 | + * | |
| 64 | + * @param mod a set of modifiers | |
| 65 | + * @return {@code true} if {@code mod} includes the | |
| 66 | + * {@code public} modifier; {@code false} otherwise. | |
| 67 | + */ | |
| 68 | + public static boolean isPublic(int mod) { | |
| 69 | + return (mod & PUBLIC) != 0; | |
| 70 | + } | |
| 71 | + | |
| 72 | + /** | |
| 73 | + * Return {@code true} if the integer argument includes the | |
| 74 | + * {@code private} modifier, {@code false} otherwise. | |
| 75 | + * | |
| 76 | + * @param mod a set of modifiers | |
| 77 | + * @return {@code true} if {@code mod} includes the | |
| 78 | + * {@code private} modifier; {@code false} otherwise. | |
| 79 | + */ | |
| 80 | + public static boolean isPrivate(int mod) { | |
| 81 | + return (mod & PRIVATE) != 0; | |
| 82 | + } | |
| 83 | + | |
| 84 | + /** | |
| 85 | + * Return {@code true} if the integer argument includes the | |
| 86 | + * {@code protected} modifier, {@code false} otherwise. | |
| 87 | + * | |
| 88 | + * @param mod a set of modifiers | |
| 89 | + * @return {@code true} if {@code mod} includes the | |
| 90 | + * {@code protected} modifier; {@code false} otherwise. | |
| 91 | + */ | |
| 92 | + public static boolean isProtected(int mod) { | |
| 93 | + return (mod & PROTECTED) != 0; | |
| 94 | + } | |
| 95 | + | |
| 96 | + /** | |
| 97 | + * Return {@code true} if the integer argument includes the | |
| 98 | + * {@code static} modifier, {@code false} otherwise. | |
| 99 | + * | |
| 100 | + * @param mod a set of modifiers | |
| 101 | + * @return {@code true} if {@code mod} includes the | |
| 102 | + * {@code static} modifier; {@code false} otherwise. | |
| 103 | + */ | |
| 104 | + public static boolean isStatic(int mod) { | |
| 105 | + return (mod & STATIC) != 0; | |
| 106 | + } | |
| 107 | + | |
| 108 | + /** | |
| 109 | + * Return {@code true} if the integer argument includes the | |
| 110 | + * {@code final} modifier, {@code false} otherwise. | |
| 111 | + * | |
| 112 | + * @param mod a set of modifiers | |
| 113 | + * @return {@code true} if {@code mod} includes the | |
| 114 | + * {@code final} modifier; {@code false} otherwise. | |
| 115 | + */ | |
| 116 | + public static boolean isFinal(int mod) { | |
| 117 | + return (mod & FINAL) != 0; | |
| 118 | + } | |
| 119 | + | |
| 120 | + /** | |
| 121 | + * Return {@code true} if the integer argument includes the | |
| 122 | + * {@code synchronized} modifier, {@code false} otherwise. | |
| 123 | + * | |
| 124 | + * @param mod a set of modifiers | |
| 125 | + * @return {@code true} if {@code mod} includes the | |
| 126 | + * {@code synchronized} modifier; {@code false} otherwise. | |
| 127 | + */ | |
| 128 | + public static boolean isSynchronized(int mod) { | |
| 129 | + return (mod & SYNCHRONIZED) != 0; | |
| 130 | + } | |
| 131 | + | |
| 132 | + /** | |
| 133 | + * Return {@code true} if the integer argument includes the | |
| 134 | + * {@code volatile} modifier, {@code false} otherwise. | |
| 135 | + * | |
| 136 | + * @param mod a set of modifiers | |
| 137 | + * @return {@code true} if {@code mod} includes the | |
| 138 | + * {@code volatile} modifier; {@code false} otherwise. | |
| 139 | + */ | |
| 140 | + public static boolean isVolatile(int mod) { | |
| 141 | + return (mod & VOLATILE) != 0; | |
| 142 | + } | |
| 143 | + | |
| 144 | + /** | |
| 145 | + * Return {@code true} if the integer argument includes the | |
| 146 | + * {@code transient} modifier, {@code false} otherwise. | |
| 147 | + * | |
| 148 | + * @param mod a set of modifiers | |
| 149 | + * @return {@code true} if {@code mod} includes the | |
| 150 | + * {@code transient} modifier; {@code false} otherwise. | |
| 151 | + */ | |
| 152 | + public static boolean isTransient(int mod) { | |
| 153 | + return (mod & TRANSIENT) != 0; | |
| 154 | + } | |
| 155 | + | |
| 156 | + /** | |
| 157 | + * Return {@code true} if the integer argument includes the | |
| 158 | + * {@code native} modifier, {@code false} otherwise. | |
| 159 | + * | |
| 160 | + * @param mod a set of modifiers | |
| 161 | + * @return {@code true} if {@code mod} includes the | |
| 162 | + * {@code native} modifier; {@code false} otherwise. | |
| 163 | + */ | |
| 164 | + public static boolean isNative(int mod) { | |
| 165 | + return (mod & NATIVE) != 0; | |
| 166 | + } | |
| 167 | + | |
| 168 | + /** | |
| 169 | + * Return {@code true} if the integer argument includes the | |
| 170 | + * {@code interface} modifier, {@code false} otherwise. | |
| 171 | + * | |
| 172 | + * @param mod a set of modifiers | |
| 173 | + * @return {@code true} if {@code mod} includes the | |
| 174 | + * {@code interface} modifier; {@code false} otherwise. | |
| 175 | + */ | |
| 176 | + public static boolean isInterface(int mod) { | |
| 177 | + return (mod & INTERFACE) != 0; | |
| 178 | + } | |
| 179 | + | |
| 180 | + /** | |
| 181 | + * Return {@code true} if the integer argument includes the | |
| 182 | + * {@code abstract} modifier, {@code false} otherwise. | |
| 183 | + * | |
| 184 | + * @param mod a set of modifiers | |
| 185 | + * @return {@code true} if {@code mod} includes the | |
| 186 | + * {@code abstract} modifier; {@code false} otherwise. | |
| 187 | + */ | |
| 188 | + public static boolean isAbstract(int mod) { | |
| 189 | + return (mod & ABSTRACT) != 0; | |
| 190 | + } | |
| 191 | + | |
| 192 | + /** | |
| 193 | + * Return {@code true} if the integer argument includes the | |
| 194 | + * {@code strictfp} modifier, {@code false} otherwise. | |
| 195 | + * | |
| 196 | + * @param mod a set of modifiers | |
| 197 | + * @return {@code true} if {@code mod} includes the | |
| 198 | + * {@code strictfp} modifier; {@code false} otherwise. | |
| 199 | + */ | |
| 200 | + public static boolean isStrict(int mod) { | |
| 201 | + return (mod & STRICT) != 0; | |
| 202 | + } | |
| 203 | + | |
| 204 | + /** | |
| 205 | + * Return a string describing the access modifier flags in | |
| 206 | + * the specified modifier. For example: | |
| 207 | + * <blockquote><pre> | |
| 208 | + * public final synchronized strictfp | |
| 209 | + * </pre></blockquote> | |
| 210 | + * The modifier names are returned in an order consistent with the | |
| 211 | + * suggested modifier orderings given in sections 8.1.1, 8.3.1, 8.4.3, 8.8.3, and 9.1.1 of | |
| 212 | + * <cite>The Java™ Language Specification</cite>. | |
| 213 | + * The full modifier ordering used by this method is: | |
| 214 | + * <blockquote> {@code | |
| 215 | + * public protected private abstract static final transient | |
| 216 | + * volatile synchronized native strictfp | |
| 217 | + * interface } </blockquote> | |
| 218 | + * The {@code interface} modifier discussed in this class is | |
| 219 | + * not a true modifier in the Java language and it appears after | |
| 220 | + * all other modifiers listed by this method. This method may | |
| 221 | + * return a string of modifiers that are not valid modifiers of a | |
| 222 | + * Java entity; in other words, no checking is done on the | |
| 223 | + * possible validity of the combination of modifiers represented | |
| 224 | + * by the input. | |
| 225 | + * | |
| 226 | + * Note that to perform such checking for a known kind of entity, | |
| 227 | + * such as a constructor or method, first AND the argument of | |
| 228 | + * {@code toString} with the appropriate mask from a method like | |
| 229 | + * {@link #constructorModifiers} or {@link #methodModifiers}. | |
| 230 | + * | |
| 231 | + * @param mod a set of modifiers | |
| 232 | + * @return a string representation of the set of modifiers | |
| 233 | + * represented by {@code mod} | |
| 234 | + */ | |
| 235 | + public static String toString(int mod) { | |
| 236 | + StringBuffer sb = new StringBuffer(); | |
| 237 | + int len; | |
| 238 | + | |
| 239 | + if ((mod & PUBLIC) != 0) sb.append("public "); | |
| 240 | + if ((mod & PROTECTED) != 0) sb.append("protected "); | |
| 241 | + if ((mod & PRIVATE) != 0) sb.append("private "); | |
| 242 | + | |
| 243 | + /* Canonical order */ | |
| 244 | + if ((mod & ABSTRACT) != 0) sb.append("abstract "); | |
| 245 | + if ((mod & STATIC) != 0) sb.append("static "); | |
| 246 | + if ((mod & FINAL) != 0) sb.append("final "); | |
| 247 | + if ((mod & TRANSIENT) != 0) sb.append("transient "); | |
| 248 | + if ((mod & VOLATILE) != 0) sb.append("volatile "); | |
| 249 | + if ((mod & SYNCHRONIZED) != 0) sb.append("synchronized "); | |
| 250 | + if ((mod & NATIVE) != 0) sb.append("native "); | |
| 251 | + if ((mod & STRICT) != 0) sb.append("strictfp "); | |
| 252 | + if ((mod & INTERFACE) != 0) sb.append("interface "); | |
| 253 | + | |
| 254 | + if ((len = sb.length()) > 0) /* trim trailing space */ | |
| 255 | + return sb.toString().substring(0, len-1); | |
| 256 | + return ""; | |
| 257 | + } | |
| 258 | + | |
| 259 | + /* | |
| 260 | + * Access modifier flag constants from tables 4.1, 4.4, 4.5, and 4.7 of | |
| 261 | + * <cite>The Java™ Virtual Machine Specification</cite> | |
| 262 | + */ | |
| 263 | + | |
| 264 | + /** | |
| 265 | + * The {@code int} value representing the {@code public} | |
| 266 | + * modifier. | |
| 267 | + */ | |
| 268 | + public static final int PUBLIC = 0x00000001; | |
| 269 | + | |
| 270 | + /** | |
| 271 | + * The {@code int} value representing the {@code private} | |
| 272 | + * modifier. | |
| 273 | + */ | |
| 274 | + public static final int PRIVATE = 0x00000002; | |
| 275 | + | |
| 276 | + /** | |
| 277 | + * The {@code int} value representing the {@code protected} | |
| 278 | + * modifier. | |
| 279 | + */ | |
| 280 | + public static final int PROTECTED = 0x00000004; | |
| 281 | + | |
| 282 | + /** | |
| 283 | + * The {@code int} value representing the {@code static} | |
| 284 | + * modifier. | |
| 285 | + */ | |
| 286 | + public static final int STATIC = 0x00000008; | |
| 287 | + | |
| 288 | + /** | |
| 289 | + * The {@code int} value representing the {@code final} | |
| 290 | + * modifier. | |
| 291 | + */ | |
| 292 | + public static final int FINAL = 0x00000010; | |
| 293 | + | |
| 294 | + /** | |
| 295 | + * The {@code int} value representing the {@code synchronized} | |
| 296 | + * modifier. | |
| 297 | + */ | |
| 298 | + public static final int SYNCHRONIZED = 0x00000020; | |
| 299 | + | |
| 300 | + /** | |
| 301 | + * The {@code int} value representing the {@code volatile} | |
| 302 | + * modifier. | |
| 303 | + */ | |
| 304 | + public static final int VOLATILE = 0x00000040; | |
| 305 | + | |
| 306 | + /** | |
| 307 | + * The {@code int} value representing the {@code transient} | |
| 308 | + * modifier. | |
| 309 | + */ | |
| 310 | + public static final int TRANSIENT = 0x00000080; | |
| 311 | + | |
| 312 | + /** | |
| 313 | + * The {@code int} value representing the {@code native} | |
| 314 | + * modifier. | |
| 315 | + */ | |
| 316 | + public static final int NATIVE = 0x00000100; | |
| 317 | + | |
| 318 | + /** | |
| 319 | + * The {@code int} value representing the {@code interface} | |
| 320 | + * modifier. | |
| 321 | + */ | |
| 322 | + public static final int INTERFACE = 0x00000200; | |
| 323 | + | |
| 324 | + /** | |
| 325 | + * The {@code int} value representing the {@code abstract} | |
| 326 | + * modifier. | |
| 327 | + */ | |
| 328 | + public static final int ABSTRACT = 0x00000400; | |
| 329 | + | |
| 330 | + /** | |
| 331 | + * The {@code int} value representing the {@code strictfp} | |
| 332 | + * modifier. | |
| 333 | + */ | |
| 334 | + public static final int STRICT = 0x00000800; | |
| 335 | + | |
| 336 | + // Bits not (yet) exposed in the public API either because they | |
| 337 | + // have different meanings for fields and methods and there is no | |
| 338 | + // way to distinguish between the two in this class, or because | |
| 339 | + // they are not Java programming language keywords | |
| 340 | + static final int BRIDGE = 0x00000040; | |
| 341 | + static final int VARARGS = 0x00000080; | |
| 342 | + static final int SYNTHETIC = 0x00001000; | |
| 343 | + static final int ANNOTATION= 0x00002000; | |
| 344 | + static final int ENUM = 0x00004000; | |
| 345 | + static boolean isSynthetic(int mod) { | |
| 346 | + return (mod & SYNTHETIC) != 0; | |
| 347 | + } | |
| 348 | + | |
| 349 | + /** | |
| 350 | + * See JLSv3 section 8.1.1. | |
| 351 | + */ | |
| 352 | + private static final int CLASS_MODIFIERS = | |
| 353 | + Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE | | |
| 354 | + Modifier.ABSTRACT | Modifier.STATIC | Modifier.FINAL | | |
| 355 | + Modifier.STRICT; | |
| 356 | + | |
| 357 | + /** | |
| 358 | + * See JLSv3 section 9.1.1. | |
| 359 | + */ | |
| 360 | + private static final int INTERFACE_MODIFIERS = | |
| 361 | + Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE | | |
| 362 | + Modifier.ABSTRACT | Modifier.STATIC | Modifier.STRICT; | |
| 363 | + | |
| 364 | + | |
| 365 | + /** | |
| 366 | + * See JLSv3 section 8.8.3. | |
| 367 | + */ | |
| 368 | + private static final int CONSTRUCTOR_MODIFIERS = | |
| 369 | + Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE; | |
| 370 | + | |
| 371 | + /** | |
| 372 | + * See JLSv3 section 8.4.3. | |
| 373 | + */ | |
| 374 | + private static final int METHOD_MODIFIERS = | |
| 375 | + Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE | | |
| 376 | + Modifier.ABSTRACT | Modifier.STATIC | Modifier.FINAL | | |
| 377 | + Modifier.SYNCHRONIZED | Modifier.NATIVE | Modifier.STRICT; | |
| 378 | + | |
| 379 | + /** | |
| 380 | + * See JLSv3 section 8.3.1. | |
| 381 | + */ | |
| 382 | + private static final int FIELD_MODIFIERS = | |
| 383 | + Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE | | |
| 384 | + Modifier.STATIC | Modifier.FINAL | Modifier.TRANSIENT | | |
| 385 | + Modifier.VOLATILE; | |
| 386 | + | |
| 387 | + /** | |
| 388 | + * Return an {@code int} value OR-ing together the source language | |
| 389 | + * modifiers that can be applied to a class. | |
| 390 | + * @return an {@code int} value OR-ing together the source language | |
| 391 | + * modifiers that can be applied to a class. | |
| 392 | + * | |
| 393 | + * @jls 8.1.1 Class Modifiers | |
| 394 | + * @since 1.7 | |
| 395 | + */ | |
| 396 | + public static int classModifiers() { | |
| 397 | + return CLASS_MODIFIERS; | |
| 398 | + } | |
| 399 | + | |
| 400 | + /** | |
| 401 | + * Return an {@code int} value OR-ing together the source language | |
| 402 | + * modifiers that can be applied to an interface. | |
| 403 | + * @return an {@code int} value OR-ing together the source language | |
| 404 | + * modifiers that can be applied to an inteface. | |
| 405 | + * | |
| 406 | + * @jls 9.1.1 Interface Modifiers | |
| 407 | + * @since 1.7 | |
| 408 | + */ | |
| 409 | + public static int interfaceModifiers() { | |
| 410 | + return INTERFACE_MODIFIERS; | |
| 411 | + } | |
| 412 | + | |
| 413 | + /** | |
| 414 | + * Return an {@code int} value OR-ing together the source language | |
| 415 | + * modifiers that can be applied to a constructor. | |
| 416 | + * @return an {@code int} value OR-ing together the source language | |
| 417 | + * modifiers that can be applied to a constructor. | |
| 418 | + * | |
| 419 | + * @jls 8.8.3 Constructor Modifiers | |
| 420 | + * @since 1.7 | |
| 421 | + */ | |
| 422 | + public static int constructorModifiers() { | |
| 423 | + return CONSTRUCTOR_MODIFIERS; | |
| 424 | + } | |
| 425 | + | |
| 426 | + /** | |
| 427 | + * Return an {@code int} value OR-ing together the source language | |
| 428 | + * modifiers that can be applied to a method. | |
| 429 | + * @return an {@code int} value OR-ing together the source language | |
| 430 | + * modifiers that can be applied to a method. | |
| 431 | + * | |
| 432 | + * @jls 8.4.3 Method Modifiers | |
| 433 | + * @since 1.7 | |
| 434 | + */ | |
| 435 | + public static int methodModifiers() { | |
| 436 | + return METHOD_MODIFIERS; | |
| 437 | + } | |
| 438 | + | |
| 439 | + | |
| 440 | + /** | |
| 441 | + * Return an {@code int} value OR-ing together the source language | |
| 442 | + * modifiers that can be applied to a field. | |
| 443 | + * @return an {@code int} value OR-ing together the source language | |
| 444 | + * modifiers that can be applied to a field. | |
| 445 | + * | |
| 446 | + * @jls 8.3.1 Field Modifiers | |
| 447 | + * @since 1.7 | |
| 448 | + */ | |
| 449 | + public static int fieldModifiers() { | |
| 450 | + return FIELD_MODIFIERS; | |
| 451 | + } | |
| 452 | +} | |
Binary file not shown.
| @@ -0,0 +1,95 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.lang.reflect; | |
| 27 | + | |
| 28 | + | |
| 29 | +/** | |
| 30 | + * ParameterizedType represents a parameterized type such as | |
| 31 | + * Collection<String>. | |
| 32 | + * | |
| 33 | + * <p>A parameterized type is created the first time it is needed by a | |
| 34 | + * reflective method, as specified in this package. When a | |
| 35 | + * parameterized type p is created, the generic type declaration that | |
| 36 | + * p instantiates is resolved, and all type arguments of p are created | |
| 37 | + * recursively. See {@link java.lang.reflect.TypeVariable | |
| 38 | + * TypeVariable} for details on the creation process for type | |
| 39 | + * variables. Repeated creation of a parameterized type has no effect. | |
| 40 | + * | |
| 41 | + * <p>Instances of classes that implement this interface must implement | |
| 42 | + * an equals() method that equates any two instances that share the | |
| 43 | + * same generic type declaration and have equal type parameters. | |
| 44 | + * | |
| 45 | + * @since 1.5 | |
| 46 | + */ | |
| 47 | +public interface ParameterizedType extends Type { | |
| 48 | + /** | |
| 49 | + * Returns an array of {@code Type} objects representing the actual type | |
| 50 | + * arguments to this type. | |
| 51 | + * | |
| 52 | + * <p>Note that in some cases, the returned array be empty. This can occur | |
| 53 | + * if this type represents a non-parameterized type nested within | |
| 54 | + * a parameterized type. | |
| 55 | + * | |
| 56 | + * @return an array of {@code Type} objects representing the actual type | |
| 57 | + * arguments to this type | |
| 58 | + * @throws TypeNotPresentException if any of the | |
| 59 | + * actual type arguments refers to a non-existent type declaration | |
| 60 | + * @throws MalformedParameterizedTypeException if any of the | |
| 61 | + * actual type parameters refer to a parameterized type that cannot | |
| 62 | + * be instantiated for any reason | |
| 63 | + * @since 1.5 | |
| 64 | + */ | |
| 65 | + Type[] getActualTypeArguments(); | |
| 66 | + | |
| 67 | + /** | |
| 68 | + * Returns the {@code Type} object representing the class or interface | |
| 69 | + * that declared this type. | |
| 70 | + * | |
| 71 | + * @return the {@code Type} object representing the class or interface | |
| 72 | + * that declared this type | |
| 73 | + * @since 1.5 | |
| 74 | + */ | |
| 75 | + Type getRawType(); | |
| 76 | + | |
| 77 | + /** | |
| 78 | + * Returns a {@code Type} object representing the type that this type | |
| 79 | + * is a member of. For example, if this type is {@code O<T>.I<S>}, | |
| 80 | + * return a representation of {@code O<T>}. | |
| 81 | + * | |
| 82 | + * <p>If this type is a top-level type, {@code null} is returned. | |
| 83 | + * | |
| 84 | + * @return a {@code Type} object representing the type that | |
| 85 | + * this type is a member of. If this type is a top-level type, | |
| 86 | + * {@code null} is returned | |
| 87 | + * @throws TypeNotPresentException if the owner type | |
| 88 | + * refers to a non-existent type declaration | |
| 89 | + * @throws MalformedParameterizedTypeException if the owner type | |
| 90 | + * refers to a parameterized type that cannot be instantiated | |
| 91 | + * for any reason | |
| 92 | + * @since 1.5 | |
| 93 | + */ | |
| 94 | + Type getOwnerType(); | |
| 95 | +} | |
Binary file not shown.
| @@ -0,0 +1,666 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.lang.reflect; | |
| 27 | + | |
| 28 | +import java.lang.ref.Reference; | |
| 29 | +import java.lang.ref.WeakReference; | |
| 30 | +import java.util.Arrays; | |
| 31 | +import java.util.Collections; | |
| 32 | +import java.util.HashMap; | |
| 33 | +import java.util.HashSet; | |
| 34 | +import java.util.Map; | |
| 35 | +import java.util.Set; | |
| 36 | +import java.util.List; | |
| 37 | +import java.util.WeakHashMap; | |
| 38 | +import sun.misc.ProxyGenerator; | |
| 39 | + | |
| 40 | +/** | |
| 41 | + * {@code Proxy} provides static methods for creating dynamic proxy | |
| 42 | + * classes and instances, and it is also the superclass of all | |
| 43 | + * dynamic proxy classes created by those methods. | |
| 44 | + * | |
| 45 | + * <p>To create a proxy for some interface {@code Foo}: | |
| 46 | + * <pre> | |
| 47 | + * InvocationHandler handler = new MyInvocationHandler(...); | |
| 48 | + * Class proxyClass = Proxy.getProxyClass( | |
| 49 | + * Foo.class.getClassLoader(), new Class[] { Foo.class }); | |
| 50 | + * Foo f = (Foo) proxyClass. | |
| 51 | + * getConstructor(new Class[] { InvocationHandler.class }). | |
| 52 | + * newInstance(new Object[] { handler }); | |
| 53 | + * </pre> | |
| 54 | + * or more simply: | |
| 55 | + * <pre> | |
| 56 | + * Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(), | |
| 57 | + * new Class[] { Foo.class }, | |
| 58 | + * handler); | |
| 59 | + * </pre> | |
| 60 | + * | |
| 61 | + * <p>A <i>dynamic proxy class</i> (simply referred to as a <i>proxy | |
| 62 | + * class</i> below) is a class that implements a list of interfaces | |
| 63 | + * specified at runtime when the class is created, with behavior as | |
| 64 | + * described below. | |
| 65 | + * | |
| 66 | + * A <i>proxy interface</i> is such an interface that is implemented | |
| 67 | + * by a proxy class. | |
| 68 | + * | |
| 69 | + * A <i>proxy instance</i> is an instance of a proxy class. | |
| 70 | + * | |
| 71 | + * Each proxy instance has an associated <i>invocation handler</i> | |
| 72 | + * object, which implements the interface {@link InvocationHandler}. | |
| 73 | + * A method invocation on a proxy instance through one of its proxy | |
| 74 | + * interfaces will be dispatched to the {@link InvocationHandler#invoke | |
| 75 | + * invoke} method of the instance's invocation handler, passing the proxy | |
| 76 | + * instance, a {@code java.lang.reflect.Method} object identifying | |
| 77 | + * the method that was invoked, and an array of type {@code Object} | |
| 78 | + * containing the arguments. The invocation handler processes the | |
| 79 | + * encoded method invocation as appropriate and the result that it | |
| 80 | + * returns will be returned as the result of the method invocation on | |
| 81 | + * the proxy instance. | |
| 82 | + * | |
| 83 | + * <p>A proxy class has the following properties: | |
| 84 | + * | |
| 85 | + * <ul> | |
| 86 | + * <li>Proxy classes are public, final, and not abstract. | |
| 87 | + * | |
| 88 | + * <li>The unqualified name of a proxy class is unspecified. The space | |
| 89 | + * of class names that begin with the string {@code "$Proxy"} | |
| 90 | + * should be, however, reserved for proxy classes. | |
| 91 | + * | |
| 92 | + * <li>A proxy class extends {@code java.lang.reflect.Proxy}. | |
| 93 | + * | |
| 94 | + * <li>A proxy class implements exactly the interfaces specified at its | |
| 95 | + * creation, in the same order. | |
| 96 | + * | |
| 97 | + * <li>If a proxy class implements a non-public interface, then it will | |
| 98 | + * be defined in the same package as that interface. Otherwise, the | |
| 99 | + * package of a proxy class is also unspecified. Note that package | |
| 100 | + * sealing will not prevent a proxy class from being successfully defined | |
| 101 | + * in a particular package at runtime, and neither will classes already | |
| 102 | + * defined by the same class loader and the same package with particular | |
| 103 | + * signers. | |
| 104 | + * | |
| 105 | + * <li>Since a proxy class implements all of the interfaces specified at | |
| 106 | + * its creation, invoking {@code getInterfaces} on its | |
| 107 | + * {@code Class} object will return an array containing the same | |
| 108 | + * list of interfaces (in the order specified at its creation), invoking | |
| 109 | + * {@code getMethods} on its {@code Class} object will return | |
| 110 | + * an array of {@code Method} objects that include all of the | |
| 111 | + * methods in those interfaces, and invoking {@code getMethod} will | |
| 112 | + * find methods in the proxy interfaces as would be expected. | |
| 113 | + * | |
| 114 | + * <li>The {@link Proxy#isProxyClass Proxy.isProxyClass} method will | |
| 115 | + * return true if it is passed a proxy class-- a class returned by | |
| 116 | + * {@code Proxy.getProxyClass} or the class of an object returned by | |
| 117 | + * {@code Proxy.newProxyInstance}-- and false otherwise. | |
| 118 | + * | |
| 119 | + * <li>The {@code java.security.ProtectionDomain} of a proxy class | |
| 120 | + * is the same as that of system classes loaded by the bootstrap class | |
| 121 | + * loader, such as {@code java.lang.Object}, because the code for a | |
| 122 | + * proxy class is generated by trusted system code. This protection | |
| 123 | + * domain will typically be granted | |
| 124 | + * {@code java.security.AllPermission}. | |
| 125 | + * | |
| 126 | + * <li>Each proxy class has one public constructor that takes one argument, | |
| 127 | + * an implementation of the interface {@link InvocationHandler}, to set | |
| 128 | + * the invocation handler for a proxy instance. Rather than having to use | |
| 129 | + * the reflection API to access the public constructor, a proxy instance | |
| 130 | + * can be also be created by calling the {@link Proxy#newProxyInstance | |
| 131 | + * Proxy.newProxyInstance} method, which combines the actions of calling | |
| 132 | + * {@link Proxy#getProxyClass Proxy.getProxyClass} with invoking the | |
| 133 | + * constructor with an invocation handler. | |
| 134 | + * </ul> | |
| 135 | + * | |
| 136 | + * <p>A proxy instance has the following properties: | |
| 137 | + * | |
| 138 | + * <ul> | |
| 139 | + * <li>Given a proxy instance {@code proxy} and one of the | |
| 140 | + * interfaces implemented by its proxy class {@code Foo}, the | |
| 141 | + * following expression will return true: | |
| 142 | + * <pre> | |
| 143 | + * {@code proxy instanceof Foo} | |
| 144 | + * </pre> | |
| 145 | + * and the following cast operation will succeed (rather than throwing | |
| 146 | + * a {@code ClassCastException}): | |
| 147 | + * <pre> | |
| 148 | + * {@code (Foo) proxy} | |
| 149 | + * </pre> | |
| 150 | + * | |
| 151 | + * <li>Each proxy instance has an associated invocation handler, the one | |
| 152 | + * that was passed to its constructor. The static | |
| 153 | + * {@link Proxy#getInvocationHandler Proxy.getInvocationHandler} method | |
| 154 | + * will return the invocation handler associated with the proxy instance | |
| 155 | + * passed as its argument. | |
| 156 | + * | |
| 157 | + * <li>An interface method invocation on a proxy instance will be | |
| 158 | + * encoded and dispatched to the invocation handler's {@link | |
| 159 | + * InvocationHandler#invoke invoke} method as described in the | |
| 160 | + * documentation for that method. | |
| 161 | + * | |
| 162 | + * <li>An invocation of the {@code hashCode}, | |
| 163 | + * {@code equals}, or {@code toString} methods declared in | |
| 164 | + * {@code java.lang.Object} on a proxy instance will be encoded and | |
| 165 | + * dispatched to the invocation handler's {@code invoke} method in | |
| 166 | + * the same manner as interface method invocations are encoded and | |
| 167 | + * dispatched, as described above. The declaring class of the | |
| 168 | + * {@code Method} object passed to {@code invoke} will be | |
| 169 | + * {@code java.lang.Object}. Other public methods of a proxy | |
| 170 | + * instance inherited from {@code java.lang.Object} are not | |
| 171 | + * overridden by a proxy class, so invocations of those methods behave | |
| 172 | + * like they do for instances of {@code java.lang.Object}. | |
| 173 | + * </ul> | |
| 174 | + * | |
| 175 | + * <h3>Methods Duplicated in Multiple Proxy Interfaces</h3> | |
| 176 | + * | |
| 177 | + * <p>When two or more interfaces of a proxy class contain a method with | |
| 178 | + * the same name and parameter signature, the order of the proxy class's | |
| 179 | + * interfaces becomes significant. When such a <i>duplicate method</i> | |
| 180 | + * is invoked on a proxy instance, the {@code Method} object passed | |
| 181 | + * to the invocation handler will not necessarily be the one whose | |
| 182 | + * declaring class is assignable from the reference type of the interface | |
| 183 | + * that the proxy's method was invoked through. This limitation exists | |
| 184 | + * because the corresponding method implementation in the generated proxy | |
| 185 | + * class cannot determine which interface it was invoked through. | |
| 186 | + * Therefore, when a duplicate method is invoked on a proxy instance, | |
| 187 | + * the {@code Method} object for the method in the foremost interface | |
| 188 | + * that contains the method (either directly or inherited through a | |
| 189 | + * superinterface) in the proxy class's list of interfaces is passed to | |
| 190 | + * the invocation handler's {@code invoke} method, regardless of the | |
| 191 | + * reference type through which the method invocation occurred. | |
| 192 | + * | |
| 193 | + * <p>If a proxy interface contains a method with the same name and | |
| 194 | + * parameter signature as the {@code hashCode}, {@code equals}, | |
| 195 | + * or {@code toString} methods of {@code java.lang.Object}, | |
| 196 | + * when such a method is invoked on a proxy instance, the | |
| 197 | + * {@code Method} object passed to the invocation handler will have | |
| 198 | + * {@code java.lang.Object} as its declaring class. In other words, | |
| 199 | + * the public, non-final methods of {@code java.lang.Object} | |
| 200 | + * logically precede all of the proxy interfaces for the determination of | |
| 201 | + * which {@code Method} object to pass to the invocation handler. | |
| 202 | + * | |
| 203 | + * <p>Note also that when a duplicate method is dispatched to an | |
| 204 | + * invocation handler, the {@code invoke} method may only throw | |
| 205 | + * checked exception types that are assignable to one of the exception | |
| 206 | + * types in the {@code throws} clause of the method in <i>all</i> of | |
| 207 | + * the proxy interfaces that it can be invoked through. If the | |
| 208 | + * {@code invoke} method throws a checked exception that is not | |
| 209 | + * assignable to any of the exception types declared by the method in one | |
| 210 | + * of the proxy interfaces that it can be invoked through, then an | |
| 211 | + * unchecked {@code UndeclaredThrowableException} will be thrown by | |
| 212 | + * the invocation on the proxy instance. This restriction means that not | |
| 213 | + * all of the exception types returned by invoking | |
| 214 | + * {@code getExceptionTypes} on the {@code Method} object | |
| 215 | + * passed to the {@code invoke} method can necessarily be thrown | |
| 216 | + * successfully by the {@code invoke} method. | |
| 217 | + * | |
| 218 | + * @author Peter Jones | |
| 219 | + * @see InvocationHandler | |
| 220 | + * @since 1.3 | |
| 221 | + */ | |
| 222 | +public class Proxy implements java.io.Serializable { | |
| 223 | + | |
| 224 | + private static final long serialVersionUID = -2222568056686623797L; | |
| 225 | + | |
| 226 | + /** prefix for all proxy class names */ | |
| 227 | + private final static String proxyClassNamePrefix = "$Proxy"; | |
| 228 | + | |
| 229 | + /** parameter types of a proxy class constructor */ | |
| 230 | + private final static Class[] constructorParams = | |
| 231 | + { InvocationHandler.class }; | |
| 232 | + | |
| 233 | + /** maps a class loader to the proxy class cache for that loader */ | |
| 234 | + private static Map<ClassLoader, Map<List<String>, Object>> loaderToCache | |
| 235 | + = new WeakHashMap<>(); | |
| 236 | + | |
| 237 | + /** marks that a particular proxy class is currently being generated */ | |
| 238 | + private static Object pendingGenerationMarker = new Object(); | |
| 239 | + | |
| 240 | + /** next number to use for generation of unique proxy class names */ | |
| 241 | + private static long nextUniqueNumber = 0; | |
| 242 | + private static Object nextUniqueNumberLock = new Object(); | |
| 243 | + | |
| 244 | + /** set of all generated proxy classes, for isProxyClass implementation */ | |
| 245 | + private static Map<Class<?>, Void> proxyClasses = | |
| 246 | + Collections.synchronizedMap(new WeakHashMap<Class<?>, Void>()); | |
| 247 | + | |
| 248 | + /** | |
| 249 | + * the invocation handler for this proxy instance. | |
| 250 | + * @serial | |
| 251 | + */ | |
| 252 | + protected InvocationHandler h; | |
| 253 | + | |
| 254 | + /** | |
| 255 | + * Prohibits instantiation. | |
| 256 | + */ | |
| 257 | + private Proxy() { | |
| 258 | + } | |
| 259 | + | |
| 260 | + /** | |
| 261 | + * Constructs a new {@code Proxy} instance from a subclass | |
| 262 | + * (typically, a dynamic proxy class) with the specified value | |
| 263 | + * for its invocation handler. | |
| 264 | + * | |
| 265 | + * @param h the invocation handler for this proxy instance | |
| 266 | + */ | |
| 267 | + protected Proxy(InvocationHandler h) { | |
| 268 | + this.h = h; | |
| 269 | + } | |
| 270 | + | |
| 271 | + /** | |
| 272 | + * Returns the {@code java.lang.Class} object for a proxy class | |
| 273 | + * given a class loader and an array of interfaces. The proxy class | |
| 274 | + * will be defined by the specified class loader and will implement | |
| 275 | + * all of the supplied interfaces. If a proxy class for the same | |
| 276 | + * permutation of interfaces has already been defined by the class | |
| 277 | + * loader, then the existing proxy class will be returned; otherwise, | |
| 278 | + * a proxy class for those interfaces will be generated dynamically | |
| 279 | + * and defined by the class loader. | |
| 280 | + * | |
| 281 | + * <p>There are several restrictions on the parameters that may be | |
| 282 | + * passed to {@code Proxy.getProxyClass}: | |
| 283 | + * | |
| 284 | + * <ul> | |
| 285 | + * <li>All of the {@code Class} objects in the | |
| 286 | + * {@code interfaces} array must represent interfaces, not | |
| 287 | + * classes or primitive types. | |
| 288 | + * | |
| 289 | + * <li>No two elements in the {@code interfaces} array may | |
| 290 | + * refer to identical {@code Class} objects. | |
| 291 | + * | |
| 292 | + * <li>All of the interface types must be visible by name through the | |
| 293 | + * specified class loader. In other words, for class loader | |
| 294 | + * {@code cl} and every interface {@code i}, the following | |
| 295 | + * expression must be true: | |
| 296 | + * <pre> | |
| 297 | + * Class.forName(i.getName(), false, cl) == i | |
| 298 | + * </pre> | |
| 299 | + * | |
| 300 | + * <li>All non-public interfaces must be in the same package; | |
| 301 | + * otherwise, it would not be possible for the proxy class to | |
| 302 | + * implement all of the interfaces, regardless of what package it is | |
| 303 | + * defined in. | |
| 304 | + * | |
| 305 | + * <li>For any set of member methods of the specified interfaces | |
| 306 | + * that have the same signature: | |
| 307 | + * <ul> | |
| 308 | + * <li>If the return type of any of the methods is a primitive | |
| 309 | + * type or void, then all of the methods must have that same | |
| 310 | + * return type. | |
| 311 | + * <li>Otherwise, one of the methods must have a return type that | |
| 312 | + * is assignable to all of the return types of the rest of the | |
| 313 | + * methods. | |
| 314 | + * </ul> | |
| 315 | + * | |
| 316 | + * <li>The resulting proxy class must not exceed any limits imposed | |
| 317 | + * on classes by the virtual machine. For example, the VM may limit | |
| 318 | + * the number of interfaces that a class may implement to 65535; in | |
| 319 | + * that case, the size of the {@code interfaces} array must not | |
| 320 | + * exceed 65535. | |
| 321 | + * </ul> | |
| 322 | + * | |
| 323 | + * <p>If any of these restrictions are violated, | |
| 324 | + * {@code Proxy.getProxyClass} will throw an | |
| 325 | + * {@code IllegalArgumentException}. If the {@code interfaces} | |
| 326 | + * array argument or any of its elements are {@code null}, a | |
| 327 | + * {@code NullPointerException} will be thrown. | |
| 328 | + * | |
| 329 | + * <p>Note that the order of the specified proxy interfaces is | |
| 330 | + * significant: two requests for a proxy class with the same combination | |
| 331 | + * of interfaces but in a different order will result in two distinct | |
| 332 | + * proxy classes. | |
| 333 | + * | |
| 334 | + * @param loader the class loader to define the proxy class | |
| 335 | + * @param interfaces the list of interfaces for the proxy class | |
| 336 | + * to implement | |
| 337 | + * @return a proxy class that is defined in the specified class loader | |
| 338 | + * and that implements the specified interfaces | |
| 339 | + * @throws IllegalArgumentException if any of the restrictions on the | |
| 340 | + * parameters that may be passed to {@code getProxyClass} | |
| 341 | + * are violated | |
| 342 | + * @throws NullPointerException if the {@code interfaces} array | |
| 343 | + * argument or any of its elements are {@code null} | |
| 344 | + */ | |
| 345 | + public static Class<?> getProxyClass(ClassLoader loader, | |
| 346 | + Class<?>... interfaces) | |
| 347 | + throws IllegalArgumentException | |
| 348 | + { | |
| 349 | + if (interfaces.length > 65535) { | |
| 350 | + throw new IllegalArgumentException("interface limit exceeded"); | |
| 351 | + } | |
| 352 | + | |
| 353 | + Class<?> proxyClass = null; | |
| 354 | + | |
| 355 | + /* collect interface names to use as key for proxy class cache */ | |
| 356 | + String[] interfaceNames = new String[interfaces.length]; | |
| 357 | + | |
| 358 | + // for detecting duplicates | |
| 359 | + Set<Class<?>> interfaceSet = new HashSet<>(); | |
| 360 | + | |
| 361 | + for (int i = 0; i < interfaces.length; i++) { | |
| 362 | + /* | |
| 363 | + * Verify that the class loader resolves the name of this | |
| 364 | + * interface to the same Class object. | |
| 365 | + */ | |
| 366 | + String interfaceName = interfaces[i].getName(); | |
| 367 | + Class<?> interfaceClass = null; | |
| 368 | + try { | |
| 369 | + interfaceClass = Class.forName(interfaceName, false, loader); | |
| 370 | + } catch (ClassNotFoundException e) { | |
| 371 | + } | |
| 372 | + if (interfaceClass != interfaces[i]) { | |
| 373 | + throw new IllegalArgumentException( | |
| 374 | + interfaces[i] + " is not visible from class loader"); | |
| 375 | + } | |
| 376 | + | |
| 377 | + /* | |
| 378 | + * Verify that the Class object actually represents an | |
| 379 | + * interface. | |
| 380 | + */ | |
| 381 | + if (!interfaceClass.isInterface()) { | |
| 382 | + throw new IllegalArgumentException( | |
| 383 | + interfaceClass.getName() + " is not an interface"); | |
| 384 | + } | |
| 385 | + | |
| 386 | + /* | |
| 387 | + * Verify that this interface is not a duplicate. | |
| 388 | + */ | |
| 389 | + if (interfaceSet.contains(interfaceClass)) { | |
| 390 | + throw new IllegalArgumentException( | |
| 391 | + "repeated interface: " + interfaceClass.getName()); | |
| 392 | + } | |
| 393 | + interfaceSet.add(interfaceClass); | |
| 394 | + | |
| 395 | + interfaceNames[i] = interfaceName; | |
| 396 | + } | |
| 397 | + | |
| 398 | + /* | |
| 399 | + * Using string representations of the proxy interfaces as | |
| 400 | + * keys in the proxy class cache (instead of their Class | |
| 401 | + * objects) is sufficient because we require the proxy | |
| 402 | + * interfaces to be resolvable by name through the supplied | |
| 403 | + * class loader, and it has the advantage that using a string | |
| 404 | + * representation of a class makes for an implicit weak | |
| 405 | + * reference to the class. | |
| 406 | + */ | |
| 407 | + List<String> key = Arrays.asList(interfaceNames); | |
| 408 | + | |
| 409 | + /* | |
| 410 | + * Find or create the proxy class cache for the class loader. | |
| 411 | + */ | |
| 412 | + Map<List<String>, Object> cache; | |
| 413 | + synchronized (loaderToCache) { | |
| 414 | + cache = loaderToCache.get(loader); | |
| 415 | + if (cache == null) { | |
| 416 | + cache = new HashMap<>(); | |
| 417 | + loaderToCache.put(loader, cache); | |
| 418 | + } | |
| 419 | + /* | |
| 420 | + * This mapping will remain valid for the duration of this | |
| 421 | + * method, without further synchronization, because the mapping | |
| 422 | + * will only be removed if the class loader becomes unreachable. | |
| 423 | + */ | |
| 424 | + } | |
| 425 | + | |
| 426 | + /* | |
| 427 | + * Look up the list of interfaces in the proxy class cache using | |
| 428 | + * the key. This lookup will result in one of three possible | |
| 429 | + * kinds of values: | |
| 430 | + * null, if there is currently no proxy class for the list of | |
| 431 | + * interfaces in the class loader, | |
| 432 | + * the pendingGenerationMarker object, if a proxy class for the | |
| 433 | + * list of interfaces is currently being generated, | |
| 434 | + * or a weak reference to a Class object, if a proxy class for | |
| 435 | + * the list of interfaces has already been generated. | |
| 436 | + */ | |
| 437 | + synchronized (cache) { | |
| 438 | + /* | |
| 439 | + * Note that we need not worry about reaping the cache for | |
| 440 | + * entries with cleared weak references because if a proxy class | |
| 441 | + * has been garbage collected, its class loader will have been | |
| 442 | + * garbage collected as well, so the entire cache will be reaped | |
| 443 | + * from the loaderToCache map. | |
| 444 | + */ | |
| 445 | + do { | |
| 446 | + Object value = cache.get(key); | |
| 447 | + if (value instanceof Reference) { | |
| 448 | + proxyClass = (Class<?>) ((Reference) value).get(); | |
| 449 | + } | |
| 450 | + if (proxyClass != null) { | |
| 451 | + // proxy class already generated: return it | |
| 452 | + return proxyClass; | |
| 453 | + } else if (value == pendingGenerationMarker) { | |
| 454 | + // proxy class being generated: wait for it | |
| 455 | + try { | |
| 456 | + cache.wait(); | |
| 457 | + } catch (InterruptedException e) { | |
| 458 | + /* | |
| 459 | + * The class generation that we are waiting for should | |
| 460 | + * take a small, bounded time, so we can safely ignore | |
| 461 | + * thread interrupts here. | |
| 462 | + */ | |
| 463 | + } | |
| 464 | + continue; | |
| 465 | + } else { | |
| 466 | + /* | |
| 467 | + * No proxy class for this list of interfaces has been | |
| 468 | + * generated or is being generated, so we will go and | |
| 469 | + * generate it now. Mark it as pending generation. | |
| 470 | + */ | |
| 471 | + cache.put(key, pendingGenerationMarker); | |
| 472 | + break; | |
| 473 | + } | |
| 474 | + } while (true); | |
| 475 | + } | |
| 476 | + | |
| 477 | + try { | |
| 478 | + String proxyPkg = null; // package to define proxy class in | |
| 479 | + | |
| 480 | + /* | |
| 481 | + * Record the package of a non-public proxy interface so that the | |
| 482 | + * proxy class will be defined in the same package. Verify that | |
| 483 | + * all non-public proxy interfaces are in the same package. | |
| 484 | + */ | |
| 485 | + for (int i = 0; i < interfaces.length; i++) { | |
| 486 | + int flags = interfaces[i].getModifiers(); | |
| 487 | + if (!Modifier.isPublic(flags)) { | |
| 488 | + String name = interfaces[i].getName(); | |
| 489 | + int n = name.lastIndexOf('.'); | |
| 490 | + String pkg = ((n == -1) ? "" : name.substring(0, n + 1)); | |
| 491 | + if (proxyPkg == null) { | |
| 492 | + proxyPkg = pkg; | |
| 493 | + } else if (!pkg.equals(proxyPkg)) { | |
| 494 | + throw new IllegalArgumentException( | |
| 495 | + "non-public interfaces from different packages"); | |
| 496 | + } | |
| 497 | + } | |
| 498 | + } | |
| 499 | + | |
| 500 | + if (proxyPkg == null) { // if no non-public proxy interfaces, | |
| 501 | + proxyPkg = ""; // use the unnamed package | |
| 502 | + } | |
| 503 | + | |
| 504 | + { | |
| 505 | + /* | |
| 506 | + * Choose a name for the proxy class to generate. | |
| 507 | + */ | |
| 508 | + long num; | |
| 509 | + synchronized (nextUniqueNumberLock) { | |
| 510 | + num = nextUniqueNumber++; | |
| 511 | + } | |
| 512 | + String proxyName = proxyPkg + proxyClassNamePrefix + num; | |
| 513 | + /* | |
| 514 | + * Verify that the class loader hasn't already | |
| 515 | + * defined a class with the chosen name. | |
| 516 | + */ | |
| 517 | + | |
| 518 | + /* | |
| 519 | + * Generate the specified proxy class. | |
| 520 | + */ | |
| 521 | + byte[] proxyClassFile = ProxyGenerator.generateProxyClass( | |
| 522 | + proxyName, interfaces); | |
| 523 | + try { | |
| 524 | + proxyClass = defineClass0(loader, proxyName, | |
| 525 | + proxyClassFile, 0, proxyClassFile.length); | |
| 526 | + } catch (ClassFormatError e) { | |
| 527 | + /* | |
| 528 | + * A ClassFormatError here means that (barring bugs in the | |
| 529 | + * proxy class generation code) there was some other | |
| 530 | + * invalid aspect of the arguments supplied to the proxy | |
| 531 | + * class creation (such as virtual machine limitations | |
| 532 | + * exceeded). | |
| 533 | + */ | |
| 534 | + throw new IllegalArgumentException(e.toString()); | |
| 535 | + } | |
| 536 | + } | |
| 537 | + // add to set of all generated proxy classes, for isProxyClass | |
| 538 | + proxyClasses.put(proxyClass, null); | |
| 539 | + | |
| 540 | + } finally { | |
| 541 | + /* | |
| 542 | + * We must clean up the "pending generation" state of the proxy | |
| 543 | + * class cache entry somehow. If a proxy class was successfully | |
| 544 | + * generated, store it in the cache (with a weak reference); | |
| 545 | + * otherwise, remove the reserved entry. In all cases, notify | |
| 546 | + * all waiters on reserved entries in this cache. | |
| 547 | + */ | |
| 548 | + synchronized (cache) { | |
| 549 | + if (proxyClass != null) { | |
| 550 | + cache.put(key, new WeakReference<Class<?>>(proxyClass)); | |
| 551 | + } else { | |
| 552 | + cache.remove(key); | |
| 553 | + } | |
| 554 | + cache.notifyAll(); | |
| 555 | + } | |
| 556 | + } | |
| 557 | + return proxyClass; | |
| 558 | + } | |
| 559 | + | |
| 560 | + /** | |
| 561 | + * Returns an instance of a proxy class for the specified interfaces | |
| 562 | + * that dispatches method invocations to the specified invocation | |
| 563 | + * handler. This method is equivalent to: | |
| 564 | + * <pre> | |
| 565 | + * Proxy.getProxyClass(loader, interfaces). | |
| 566 | + * getConstructor(new Class[] { InvocationHandler.class }). | |
| 567 | + * newInstance(new Object[] { handler }); | |
| 568 | + * </pre> | |
| 569 | + * | |
| 570 | + * <p>{@code Proxy.newProxyInstance} throws | |
| 571 | + * {@code IllegalArgumentException} for the same reasons that | |
| 572 | + * {@code Proxy.getProxyClass} does. | |
| 573 | + * | |
| 574 | + * @param loader the class loader to define the proxy class | |
| 575 | + * @param interfaces the list of interfaces for the proxy class | |
| 576 | + * to implement | |
| 577 | + * @param h the invocation handler to dispatch method invocations to | |
| 578 | + * @return a proxy instance with the specified invocation handler of a | |
| 579 | + * proxy class that is defined by the specified class loader | |
| 580 | + * and that implements the specified interfaces | |
| 581 | + * @throws IllegalArgumentException if any of the restrictions on the | |
| 582 | + * parameters that may be passed to {@code getProxyClass} | |
| 583 | + * are violated | |
| 584 | + * @throws NullPointerException if the {@code interfaces} array | |
| 585 | + * argument or any of its elements are {@code null}, or | |
| 586 | + * if the invocation handler, {@code h}, is | |
| 587 | + * {@code null} | |
| 588 | + */ | |
| 589 | + public static Object newProxyInstance(ClassLoader loader, | |
| 590 | + Class<?>[] interfaces, | |
| 591 | + InvocationHandler h) | |
| 592 | + throws IllegalArgumentException | |
| 593 | + { | |
| 594 | + if (h == null) { | |
| 595 | + throw new NullPointerException(); | |
| 596 | + } | |
| 597 | + | |
| 598 | + /* | |
| 599 | + * Look up or generate the designated proxy class. | |
| 600 | + */ | |
| 601 | + Class<?> cl = getProxyClass(loader, interfaces); | |
| 602 | + | |
| 603 | + /* | |
| 604 | + * Invoke its constructor with the designated invocation handler. | |
| 605 | + */ | |
| 606 | + try { | |
| 607 | + Constructor cons = cl.getConstructor(constructorParams); | |
| 608 | + return cons.newInstance(new Object[] { h }); | |
| 609 | + } catch (NoSuchMethodException e) { | |
| 610 | + throw new InternalError(e.toString()); | |
| 611 | + } catch (IllegalAccessException e) { | |
| 612 | + throw new InternalError(e.toString()); | |
| 613 | + } catch (InstantiationException e) { | |
| 614 | + throw new InternalError(e.toString()); | |
| 615 | + } catch (InvocationTargetException e) { | |
| 616 | + throw new InternalError(e.toString()); | |
| 617 | + } | |
| 618 | + } | |
| 619 | + | |
| 620 | + /** | |
| 621 | + * Returns true if and only if the specified class was dynamically | |
| 622 | + * generated to be a proxy class using the {@code getProxyClass} | |
| 623 | + * method or the {@code newProxyInstance} method. | |
| 624 | + * | |
| 625 | + * <p>The reliability of this method is important for the ability | |
| 626 | + * to use it to make security decisions, so its implementation should | |
| 627 | + * not just test if the class in question extends {@code Proxy}. | |
| 628 | + * | |
| 629 | + * @param cl the class to test | |
| 630 | + * @return {@code true} if the class is a proxy class and | |
| 631 | + * {@code false} otherwise | |
| 632 | + * @throws NullPointerException if {@code cl} is {@code null} | |
| 633 | + */ | |
| 634 | + public static boolean isProxyClass(Class<?> cl) { | |
| 635 | + if (cl == null) { | |
| 636 | + throw new NullPointerException(); | |
| 637 | + } | |
| 638 | + | |
| 639 | + return proxyClasses.containsKey(cl); | |
| 640 | + } | |
| 641 | + | |
| 642 | + /** | |
| 643 | + * Returns the invocation handler for the specified proxy instance. | |
| 644 | + * | |
| 645 | + * @param proxy the proxy instance to return the invocation handler for | |
| 646 | + * @return the invocation handler for the proxy instance | |
| 647 | + * @throws IllegalArgumentException if the argument is not a | |
| 648 | + * proxy instance | |
| 649 | + */ | |
| 650 | + public static InvocationHandler getInvocationHandler(Object proxy) | |
| 651 | + throws IllegalArgumentException | |
| 652 | + { | |
| 653 | + /* | |
| 654 | + * Verify that the object is actually a proxy instance. | |
| 655 | + */ | |
| 656 | + if (!isProxyClass(proxy.getClass())) { | |
| 657 | + throw new IllegalArgumentException("not a proxy instance"); | |
| 658 | + } | |
| 659 | + | |
| 660 | + Proxy p = (Proxy) proxy; | |
| 661 | + return p.h; | |
| 662 | + } | |
| 663 | + | |
| 664 | + private static native Class defineClass0(ClassLoader loader, String name, | |
| 665 | + byte[] b, int off, int len); | |
| 666 | +} | |
Binary file not shown.
| @@ -0,0 +1,146 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.lang.reflect; | |
| 27 | + | |
| 28 | +import sun.reflect.MethodAccessor; | |
| 29 | +import sun.reflect.ConstructorAccessor; | |
| 30 | + | |
| 31 | +/** Package-private class implementing the | |
| 32 | + sun.reflect.LangReflectAccess interface, allowing the java.lang | |
| 33 | + package to instantiate objects in this package. */ | |
| 34 | + | |
| 35 | +class ReflectAccess implements sun.reflect.LangReflectAccess { | |
| 36 | + public Field newField(Class<?> declaringClass, | |
| 37 | + String name, | |
| 38 | + Class<?> type, | |
| 39 | + int modifiers, | |
| 40 | + int slot, | |
| 41 | + String signature, | |
| 42 | + byte[] annotations) | |
| 43 | + { | |
| 44 | + return new Field(declaringClass, | |
| 45 | + name, | |
| 46 | + type, | |
| 47 | + modifiers, | |
| 48 | + slot, | |
| 49 | + signature, | |
| 50 | + annotations); | |
| 51 | + } | |
| 52 | + | |
| 53 | + public Method newMethod(Class<?> declaringClass, | |
| 54 | + String name, | |
| 55 | + Class<?>[] parameterTypes, | |
| 56 | + Class<?> returnType, | |
| 57 | + Class<?>[] checkedExceptions, | |
| 58 | + int modifiers, | |
| 59 | + int slot, | |
| 60 | + String signature, | |
| 61 | + byte[] annotations, | |
| 62 | + byte[] parameterAnnotations, | |
| 63 | + byte[] annotationDefault) | |
| 64 | + { | |
| 65 | + return new Method(declaringClass, | |
| 66 | + name, | |
| 67 | + parameterTypes, | |
| 68 | + returnType, | |
| 69 | + checkedExceptions, | |
| 70 | + modifiers, | |
| 71 | + slot, | |
| 72 | + signature, | |
| 73 | + annotations, | |
| 74 | + parameterAnnotations, | |
| 75 | + annotationDefault); | |
| 76 | + } | |
| 77 | + | |
| 78 | + public <T> Constructor<T> newConstructor(Class<T> declaringClass, | |
| 79 | + Class<?>[] parameterTypes, | |
| 80 | + Class<?>[] checkedExceptions, | |
| 81 | + int modifiers, | |
| 82 | + int slot, | |
| 83 | + String signature, | |
| 84 | + byte[] annotations, | |
| 85 | + byte[] parameterAnnotations) | |
| 86 | + { | |
| 87 | + return new Constructor<>(declaringClass, | |
| 88 | + parameterTypes, | |
| 89 | + checkedExceptions, | |
| 90 | + modifiers, | |
| 91 | + slot, | |
| 92 | + signature, | |
| 93 | + annotations, | |
| 94 | + parameterAnnotations); | |
| 95 | + } | |
| 96 | + | |
| 97 | + public MethodAccessor getMethodAccessor(Method m) { | |
| 98 | + return m.getMethodAccessor(); | |
| 99 | + } | |
| 100 | + | |
| 101 | + public void setMethodAccessor(Method m, MethodAccessor accessor) { | |
| 102 | + m.setMethodAccessor(accessor); | |
| 103 | + } | |
| 104 | + | |
| 105 | + public ConstructorAccessor getConstructorAccessor(Constructor<?> c) { | |
| 106 | + return c.getConstructorAccessor(); | |
| 107 | + } | |
| 108 | + | |
| 109 | + public void setConstructorAccessor(Constructor<?> c, | |
| 110 | + ConstructorAccessor accessor) | |
| 111 | + { | |
| 112 | + c.setConstructorAccessor(accessor); | |
| 113 | + } | |
| 114 | + | |
| 115 | + public int getConstructorSlot(Constructor<?> c) { | |
| 116 | + return c.getSlot(); | |
| 117 | + } | |
| 118 | + | |
| 119 | + public String getConstructorSignature(Constructor<?> c) { | |
| 120 | + return c.getSignature(); | |
| 121 | + } | |
| 122 | + | |
| 123 | + public byte[] getConstructorAnnotations(Constructor<?> c) { | |
| 124 | + return c.getRawAnnotations(); | |
| 125 | + } | |
| 126 | + | |
| 127 | + public byte[] getConstructorParameterAnnotations(Constructor<?> c) { | |
| 128 | + return c.getRawParameterAnnotations(); | |
| 129 | + } | |
| 130 | + | |
| 131 | + // | |
| 132 | + // Copying routines, needed to quickly fabricate new Field, | |
| 133 | + // Method, and Constructor objects from templates | |
| 134 | + // | |
| 135 | + public Method copyMethod(Method arg) { | |
| 136 | + return arg.copy(); | |
| 137 | + } | |
| 138 | + | |
| 139 | + public Field copyField(Field arg) { | |
| 140 | + return arg.copy(); | |
| 141 | + } | |
| 142 | + | |
| 143 | + public <T> Constructor<T> copyConstructor(Constructor<T> arg) { | |
| 144 | + return arg.copy(); | |
| 145 | + } | |
| 146 | +} | |
Binary file not shown.
| @@ -0,0 +1,101 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 1997, 2004, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.lang.reflect; | |
| 27 | + | |
| 28 | +/** | |
| 29 | + * The Permission class for reflective operations. A | |
| 30 | + * ReflectPermission is a <em>named permission</em> and has no | |
| 31 | + * actions. The only name currently defined is {@code suppressAccessChecks}, | |
| 32 | + * which allows suppressing the standard Java language access checks | |
| 33 | + * -- for public, default (package) access, protected, and private | |
| 34 | + * members -- performed by reflected objects at their point of use. | |
| 35 | + * <P> | |
| 36 | + * The following table | |
| 37 | + * provides a summary description of what the permission allows, | |
| 38 | + * and discusses the risks of granting code the permission. | |
| 39 | + * <P> | |
| 40 | + * | |
| 41 | + * <table border=1 cellpadding=5 summary="Table shows permission target name, what the permission allows, and associated risks"> | |
| 42 | + * <tr> | |
| 43 | + * <th>Permission Target Name</th> | |
| 44 | + * <th>What the Permission Allows</th> | |
| 45 | + * <th>Risks of Allowing this Permission</th> | |
| 46 | + * </tr> | |
| 47 | + * | |
| 48 | + * <tr> | |
| 49 | + * <td>suppressAccessChecks</td> | |
| 50 | + * <td>ability to access | |
| 51 | + * fields and invoke methods in a class. Note that this includes | |
| 52 | + * not only public, but protected and private fields and methods as well.</td> | |
| 53 | + * <td>This is dangerous in that information (possibly confidential) and | |
| 54 | + * methods normally unavailable would be accessible to malicious code.</td> | |
| 55 | + * </tr> | |
| 56 | + * | |
| 57 | + * </table> | |
| 58 | + * | |
| 59 | + * @see java.security.Permission | |
| 60 | + * @see java.security.BasicPermission | |
| 61 | + * @see AccessibleObject | |
| 62 | + * @see Field#get | |
| 63 | + * @see Field#set | |
| 64 | + * @see Method#invoke | |
| 65 | + * @see Constructor#newInstance | |
| 66 | + * | |
| 67 | + * @since 1.2 | |
| 68 | + */ | |
| 69 | +public final | |
| 70 | +class ReflectPermission extends java.security.BasicPermission { | |
| 71 | + | |
| 72 | + private static final long serialVersionUID = 7412737110241507485L; | |
| 73 | + | |
| 74 | + /** | |
| 75 | + * Constructs a ReflectPermission with the specified name. | |
| 76 | + * | |
| 77 | + * @param name the name of the ReflectPermission | |
| 78 | + * | |
| 79 | + * @throws NullPointerException if {@code name} is {@code null}. | |
| 80 | + * @throws IllegalArgumentException if {@code name} is empty. | |
| 81 | + */ | |
| 82 | + public ReflectPermission(String name) { | |
| 83 | + super(name); | |
| 84 | + } | |
| 85 | + | |
| 86 | + /** | |
| 87 | + * Constructs a ReflectPermission with the specified name and actions. | |
| 88 | + * The actions should be null; they are ignored. | |
| 89 | + * | |
| 90 | + * @param name the name of the ReflectPermission | |
| 91 | + * | |
| 92 | + * @param actions should be null | |
| 93 | + * | |
| 94 | + * @throws NullPointerException if {@code name} is {@code null}. | |
| 95 | + * @throws IllegalArgumentException if {@code name} is empty. | |
| 96 | + */ | |
| 97 | + public ReflectPermission(String name, String actions) { | |
| 98 | + super(name, actions); | |
| 99 | + } | |
| 100 | + | |
| 101 | +} | |
Binary file not shown.
| @@ -0,0 +1,37 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.lang.reflect; | |
| 27 | + | |
| 28 | +/** | |
| 29 | + * Type is the common superinterface for all types in the Java | |
| 30 | + * programming language. These include raw types, parameterized types, | |
| 31 | + * array types, type variables and primitive types. | |
| 32 | + * | |
| 33 | + * @since 1.5 | |
| 34 | + */ | |
| 35 | + | |
| 36 | +public interface Type { | |
| 37 | +} | |
Binary file not shown.
| @@ -0,0 +1,89 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.lang.reflect; | |
| 27 | + | |
| 28 | +/** | |
| 29 | + * TypeVariable is the common superinterface for type variables of kinds. | |
| 30 | + * A type variable is created the first time it is needed by a reflective | |
| 31 | + * method, as specified in this package. If a type variable t is referenced | |
| 32 | + * by a type (i.e, class, interface or annotation type) T, and T is declared | |
| 33 | + * by the nth enclosing class of T (see JLS 8.1.2), then the creation of t | |
| 34 | + * requires the resolution (see JVMS 5) of the ith enclosing class of T, | |
| 35 | + * for i = 0 to n, inclusive. Creating a type variable must not cause the | |
| 36 | + * creation of its bounds. Repeated creation of a type variable has no effect. | |
| 37 | + * | |
| 38 | + * <p>Multiple objects may be instantiated at run-time to | |
| 39 | + * represent a given type variable. Even though a type variable is | |
| 40 | + * created only once, this does not imply any requirement to cache | |
| 41 | + * instances representing the type variable. However, all instances | |
| 42 | + * representing a type variable must be equal() to each other. | |
| 43 | + * As a consequence, users of type variables must not rely on the identity | |
| 44 | + * of instances of classes implementing this interface. | |
| 45 | + * | |
| 46 | + * @param <D> the type of generic declaration that declared the | |
| 47 | + * underlying type variable. | |
| 48 | + * | |
| 49 | + * @since 1.5 | |
| 50 | + */ | |
| 51 | +public interface TypeVariable<D extends GenericDeclaration> extends Type { | |
| 52 | + /** | |
| 53 | + * Returns an array of {@code Type} objects representing the | |
| 54 | + * upper bound(s) of this type variable. Note that if no upper bound is | |
| 55 | + * explicitly declared, the upper bound is {@code Object}. | |
| 56 | + * | |
| 57 | + * <p>For each upper bound B: <ul> <li>if B is a parameterized | |
| 58 | + * type or a type variable, it is created, (see {@link | |
| 59 | + * java.lang.reflect.ParameterizedType ParameterizedType} for the | |
| 60 | + * details of the creation process for parameterized types). | |
| 61 | + * <li>Otherwise, B is resolved. </ul> | |
| 62 | + * | |
| 63 | + * @throws TypeNotPresentException if any of the | |
| 64 | + * bounds refers to a non-existent type declaration | |
| 65 | + * @throws MalformedParameterizedTypeException if any of the | |
| 66 | + * bounds refer to a parameterized type that cannot be instantiated | |
| 67 | + * for any reason | |
| 68 | + * @return an array of {@code Type}s representing the upper | |
| 69 | + * bound(s) of this type variable | |
| 70 | + */ | |
| 71 | + Type[] getBounds(); | |
| 72 | + | |
| 73 | + /** | |
| 74 | + * Returns the {@code GenericDeclaration} object representing the | |
| 75 | + * generic declaration declared this type variable. | |
| 76 | + * | |
| 77 | + * @return the generic declaration declared for this type variable. | |
| 78 | + * | |
| 79 | + * @since 1.5 | |
| 80 | + */ | |
| 81 | + D getGenericDeclaration(); | |
| 82 | + | |
| 83 | + /** | |
| 84 | + * Returns the name of this type variable, as it occurs in the source code. | |
| 85 | + * | |
| 86 | + * @return the name of this type variable, as it appears in the source code | |
| 87 | + */ | |
| 88 | + String getName(); | |
| 89 | +} | |
Binary file not shown.
| @@ -0,0 +1,119 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 1999, 2006, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.lang.reflect; | |
| 27 | + | |
| 28 | +/** | |
| 29 | + * Thrown by a method invocation on a proxy instance if its invocation | |
| 30 | + * handler's {@link InvocationHandler#invoke invoke} method throws a | |
| 31 | + * checked exception (a {@code Throwable} that is not assignable | |
| 32 | + * to {@code RuntimeException} or {@code Error}) that | |
| 33 | + * is not assignable to any of the exception types declared in the | |
| 34 | + * {@code throws} clause of the method that was invoked on the | |
| 35 | + * proxy instance and dispatched to the invocation handler. | |
| 36 | + * | |
| 37 | + * <p>An {@code UndeclaredThrowableException} instance contains | |
| 38 | + * the undeclared checked exception that was thrown by the invocation | |
| 39 | + * handler, and it can be retrieved with the | |
| 40 | + * {@code getUndeclaredThrowable()} method. | |
| 41 | + * {@code UndeclaredThrowableException} extends | |
| 42 | + * {@code RuntimeException}, so it is an unchecked exception | |
| 43 | + * that wraps a checked exception. | |
| 44 | + * | |
| 45 | + * <p>As of release 1.4, this exception has been retrofitted to | |
| 46 | + * conform to the general purpose exception-chaining mechanism. The | |
| 47 | + * "undeclared checked exception that was thrown by the invocation | |
| 48 | + * handler" that may be provided at construction time and accessed via | |
| 49 | + * the {@link #getUndeclaredThrowable()} method is now known as the | |
| 50 | + * <i>cause</i>, and may be accessed via the {@link | |
| 51 | + * Throwable#getCause()} method, as well as the aforementioned "legacy | |
| 52 | + * method." | |
| 53 | + * | |
| 54 | + * @author Peter Jones | |
| 55 | + * @see InvocationHandler | |
| 56 | + * @since 1.3 | |
| 57 | + */ | |
| 58 | +public class UndeclaredThrowableException extends RuntimeException { | |
| 59 | + static final long serialVersionUID = 330127114055056639L; | |
| 60 | + | |
| 61 | + /** | |
| 62 | + * the undeclared checked exception that was thrown | |
| 63 | + * @serial | |
| 64 | + */ | |
| 65 | + private Throwable undeclaredThrowable; | |
| 66 | + | |
| 67 | + /** | |
| 68 | + * Constructs an {@code UndeclaredThrowableException} with the | |
| 69 | + * specified {@code Throwable}. | |
| 70 | + * | |
| 71 | + * @param undeclaredThrowable the undeclared checked exception | |
| 72 | + * that was thrown | |
| 73 | + */ | |
| 74 | + public UndeclaredThrowableException(Throwable undeclaredThrowable) { | |
| 75 | + super((Throwable) null); // Disallow initCause | |
| 76 | + this.undeclaredThrowable = undeclaredThrowable; | |
| 77 | + } | |
| 78 | + | |
| 79 | + /** | |
| 80 | + * Constructs an {@code UndeclaredThrowableException} with the | |
| 81 | + * specified {@code Throwable} and a detail message. | |
| 82 | + * | |
| 83 | + * @param undeclaredThrowable the undeclared checked exception | |
| 84 | + * that was thrown | |
| 85 | + * @param s the detail message | |
| 86 | + */ | |
| 87 | + public UndeclaredThrowableException(Throwable undeclaredThrowable, | |
| 88 | + String s) | |
| 89 | + { | |
| 90 | + super(s, null); // Disallow initCause | |
| 91 | + this.undeclaredThrowable = undeclaredThrowable; | |
| 92 | + } | |
| 93 | + | |
| 94 | + /** | |
| 95 | + * Returns the {@code Throwable} instance wrapped in this | |
| 96 | + * {@code UndeclaredThrowableException}, which may be {@code null}. | |
| 97 | + * | |
| 98 | + * <p>This method predates the general-purpose exception chaining facility. | |
| 99 | + * The {@link Throwable#getCause()} method is now the preferred means of | |
| 100 | + * obtaining this information. | |
| 101 | + * | |
| 102 | + * @return the undeclared checked exception that was thrown | |
| 103 | + */ | |
| 104 | + public Throwable getUndeclaredThrowable() { | |
| 105 | + return undeclaredThrowable; | |
| 106 | + } | |
| 107 | + | |
| 108 | + /** | |
| 109 | + * Returns the cause of this exception (the {@code Throwable} | |
| 110 | + * instance wrapped in this {@code UndeclaredThrowableException}, | |
| 111 | + * which may be {@code null}). | |
| 112 | + * | |
| 113 | + * @return the cause of this exception. | |
| 114 | + * @since 1.4 | |
| 115 | + */ | |
| 116 | + public Throwable getCause() { | |
| 117 | + return undeclaredThrowable; | |
| 118 | + } | |
| 119 | +} | |
Binary file not shown.
| @@ -0,0 +1,83 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.lang.reflect; | |
| 27 | + | |
| 28 | +/** | |
| 29 | + * WildcardType represents a wildcard type expression, such as | |
| 30 | + * {@code ?}, {@code ? extends Number}, or {@code ? super Integer}. | |
| 31 | + * | |
| 32 | + * @since 1.5 | |
| 33 | + */ | |
| 34 | +public interface WildcardType extends Type { | |
| 35 | + /** | |
| 36 | + * Returns an array of {@code Type} objects representing the upper | |
| 37 | + * bound(s) of this type variable. Note that if no upper bound is | |
| 38 | + * explicitly declared, the upper bound is {@code Object}. | |
| 39 | + * | |
| 40 | + * <p>For each upper bound B : | |
| 41 | + * <ul> | |
| 42 | + * <li>if B is a parameterized type or a type variable, it is created, | |
| 43 | + * (see {@link java.lang.reflect.ParameterizedType ParameterizedType} | |
| 44 | + * for the details of the creation process for parameterized types). | |
| 45 | + * <li>Otherwise, B is resolved. | |
| 46 | + * </ul> | |
| 47 | + * | |
| 48 | + * @return an array of Types representing the upper bound(s) of this | |
| 49 | + * type variable | |
| 50 | + * @throws TypeNotPresentException if any of the | |
| 51 | + * bounds refers to a non-existent type declaration | |
| 52 | + * @throws MalformedParameterizedTypeException if any of the | |
| 53 | + * bounds refer to a parameterized type that cannot be instantiated | |
| 54 | + * for any reason | |
| 55 | + */ | |
| 56 | + Type[] getUpperBounds(); | |
| 57 | + | |
| 58 | + /** | |
| 59 | + * Returns an array of {@code Type} objects representing the | |
| 60 | + * lower bound(s) of this type variable. Note that if no lower bound is | |
| 61 | + * explicitly declared, the lower bound is the type of {@code null}. | |
| 62 | + * In this case, a zero length array is returned. | |
| 63 | + * | |
| 64 | + * <p>For each lower bound B : | |
| 65 | + * <ul> | |
| 66 | + * <li>if B is a parameterized type or a type variable, it is created, | |
| 67 | + * (see {@link java.lang.reflect.ParameterizedType ParameterizedType} | |
| 68 | + * for the details of the creation process for parameterized types). | |
| 69 | + * <li>Otherwise, B is resolved. | |
| 70 | + * </ul> | |
| 71 | + * | |
| 72 | + * @return an array of Types representing the lower bound(s) of this | |
| 73 | + * type variable | |
| 74 | + * @throws TypeNotPresentException if any of the | |
| 75 | + * bounds refers to a non-existent type declaration | |
| 76 | + * @throws MalformedParameterizedTypeException if any of the | |
| 77 | + * bounds refer to a parameterized type that cannot be instantiated | |
| 78 | + * for any reason | |
| 79 | + */ | |
| 80 | + Type[] getLowerBounds(); | |
| 81 | + // one or many? Up to language spec; currently only one, but this API | |
| 82 | + // allows for generalization. | |
| 83 | +} | |
| @@ -0,0 +1,30 @@ | ||
| 1 | +<../../../../../mkconfig | |
| 2 | + | |
| 3 | +TARG=\ | |
| 4 | + AccessibleObject.dis\ | |
| 5 | + AnnotatedElement.dis\ | |
| 6 | + Array.dis\ | |
| 7 | + Constructor.dis\ | |
| 8 | + Field.dis\ | |
| 9 | + GenericArrayType.dis\ | |
| 10 | + GenericDeclaration.dis\ | |
| 11 | + GenericSignatureFormatError.dis\ | |
| 12 | + InvocationHandler.dis\ | |
| 13 | + InvocationTargetException.dis\ | |
| 14 | + MalformedParameterizedTypeException.dis\ | |
| 15 | + Member.dis\ | |
| 16 | + Method.dis\ | |
| 17 | + Modifier.dis\ | |
| 18 | + package-info.dis\ | |
| 19 | + ParameterizedType.dis\ | |
| 20 | + Proxy.dis\ | |
| 21 | + ReflectAccess.dis\ | |
| 22 | + ReflectPermission.dis\ | |
| 23 | + Type.dis\ | |
| 24 | + TypeVariable.dis\ | |
| 25 | + UndeclaredThrowableException.dis\ | |
| 26 | + WildcardType.dis\ | |
| 27 | + | |
| 28 | +DISBIN=$ROOT/java/dis/java/java/java/lang/reflect | |
| 29 | + | |
| 30 | +<$ROOT/mkfiles/mkjava | |
| @@ -0,0 +1,49 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +/** | |
| 27 | + * Provides classes and interfaces for obtaining reflective | |
| 28 | + * information about classes and objects. Reflection allows | |
| 29 | + * programmatic access to information about the fields, methods and | |
| 30 | + * constructors of loaded classes, and the use of reflected fields, | |
| 31 | + * methods, and constructors to operate on their underlying | |
| 32 | + * counterparts, within security restrictions. | |
| 33 | + * | |
| 34 | + * <p>{@code AccessibleObject} allows suppression of access checks if | |
| 35 | + * the necessary {@code ReflectPermission} is available. | |
| 36 | + * | |
| 37 | + * <p>{@code Array} provides static methods to dynamically create and | |
| 38 | + * access arrays. | |
| 39 | + * | |
| 40 | + * <p>Classes in this package, along with {@code java.lang.Class} | |
| 41 | + * accommodate applications such as debuggers, interpreters, object | |
| 42 | + * inspectors, class browsers, and services such as Object | |
| 43 | + * Serialization and JavaBeans that need access to either the public | |
| 44 | + * members of a target object (based on its runtime class) or the | |
| 45 | + * members declared by a given class. | |
| 46 | + * | |
| 47 | + * @since JDK1.1 | |
| 48 | + */ | |
| 49 | +package java.lang.reflect; | |
| @@ -0,0 +1,327 @@ | ||
| 1 | +implement Reflect; | |
| 2 | + | |
| 3 | +include "jni.m"; | |
| 4 | + jni : JNI; | |
| 5 | + cast : Cast; | |
| 6 | + | |
| 7 | + JObject, | |
| 8 | + JClass, | |
| 9 | + JArrayJClass, | |
| 10 | + JArrayJObject, | |
| 11 | + Value : import jni; | |
| 12 | + OK, | |
| 13 | + ERR, | |
| 14 | + TRUE, | |
| 15 | + FALSE, | |
| 16 | + #T_OBJECT, T_ARRAY, | |
| 17 | + T_BOOLEAN, | |
| 18 | + T_BYTE, | |
| 19 | + T_CHAR, | |
| 20 | + T_SHORT, | |
| 21 | + T_INT, | |
| 22 | + T_LONG, | |
| 23 | + T_FLOAT, | |
| 24 | + T_DOUBLE : import JNI; | |
| 25 | + | |
| 26 | + ClassData : import JNI; | |
| 27 | + | |
| 28 | +include "reflect.m"; | |
| 29 | + | |
| 30 | +wrapper_class := array[T_LONG-T_BOOLEAN+1] of ClassData; | |
| 31 | +wrapper_name := array[] of { "Boolean", | |
| 32 | + "Character", | |
| 33 | + "Float", | |
| 34 | + "Double", | |
| 35 | + "Byte", | |
| 36 | + "Short", | |
| 37 | + "Integer", | |
| 38 | + "Long" }; | |
| 39 | +type_string := "ZCFDBSIJ"; | |
| 40 | + | |
| 41 | +illegalarg := "java.lang.IllegalArgumentException"; | |
| 42 | +nullptr := "java.lang.NullPointerException"; | |
| 43 | + | |
| 44 | +init(jni_m : JNI) { | |
| 45 | + jni = jni_m; | |
| 46 | + for ( i := 0; i <= T_LONG - T_BOOLEAN; i++ ) | |
| 47 | + wrapper_class[i] = jni->FindClass("java/lang/" + wrapper_name[i]); | |
| 48 | + cast = jni->CastMod(); | |
| 49 | +} | |
| 50 | + | |
| 51 | +widen(have, want : int, val : ref Value) : ref Value | |
| 52 | +{ | |
| 53 | + if ( have == want ) | |
| 54 | + return val; | |
| 55 | + havetype := have; | |
| 56 | + wanttype := want; | |
| 57 | + valint : int; | |
| 58 | + valbig : big; | |
| 59 | + valreal : real; | |
| 60 | + if ( havetype == 0 || wanttype == 0 ) | |
| 61 | + return nil; | |
| 62 | + pick sw := val { | |
| 63 | + TByte => | |
| 64 | + valint = int sw.jbyte; | |
| 65 | + valbig = big valint; | |
| 66 | + valreal = real valint; | |
| 67 | + TShort => | |
| 68 | + valint = sw.jshort; | |
| 69 | + valbig = big valint; | |
| 70 | + valreal = real valint; | |
| 71 | + TChar => | |
| 72 | + valint = sw.jchar; | |
| 73 | + valbig = big valint; | |
| 74 | + valreal = real valint; | |
| 75 | + TInt => | |
| 76 | + valint = sw.jint; | |
| 77 | + valbig = big valint; | |
| 78 | + valreal = real valint; | |
| 79 | + TLong => | |
| 80 | + valbig = sw.jlong; | |
| 81 | + valreal = real valbig; | |
| 82 | + TFloat => | |
| 83 | + valreal = sw.jfloat; | |
| 84 | + } | |
| 85 | + case ( wanttype ) { | |
| 86 | + T_BOOLEAN or T_BYTE or T_CHAR => | |
| 87 | + return nil; | |
| 88 | + T_SHORT => | |
| 89 | + case ( havetype ) { | |
| 90 | + T_BYTE => | |
| 91 | + sw := ref Value.TShort; | |
| 92 | + sw.jshort = valint; | |
| 93 | + val = sw; | |
| 94 | + * => | |
| 95 | + return nil; | |
| 96 | + } | |
| 97 | + T_INT => | |
| 98 | + case ( havetype ) { | |
| 99 | + T_BYTE or T_SHORT or T_CHAR => | |
| 100 | + sw := ref Value.TInt; | |
| 101 | + sw.jint = valint; | |
| 102 | + val = sw; | |
| 103 | + * => | |
| 104 | + return nil; | |
| 105 | + } | |
| 106 | + T_LONG => | |
| 107 | + case ( havetype ) { | |
| 108 | + T_BYTE or T_SHORT or T_CHAR or T_INT => | |
| 109 | + sw := ref Value.TLong; | |
| 110 | + sw.jlong = valbig; | |
| 111 | + val = sw; | |
| 112 | + * => | |
| 113 | + return nil; | |
| 114 | + } | |
| 115 | + T_FLOAT => | |
| 116 | + case ( havetype ) { | |
| 117 | + T_BYTE or T_SHORT or T_CHAR or T_INT or T_LONG => | |
| 118 | + sw := ref Value.TFloat; | |
| 119 | + sw.jfloat = valreal; | |
| 120 | + val = sw; | |
| 121 | + * => | |
| 122 | + return nil; | |
| 123 | + } | |
| 124 | + T_DOUBLE => | |
| 125 | + case ( havetype ) { | |
| 126 | + T_BYTE or T_SHORT or T_CHAR or T_INT or T_LONG or T_FLOAT => | |
| 127 | + sw := ref Value.TDouble; | |
| 128 | + sw.jdouble = valreal; | |
| 129 | + val = sw; | |
| 130 | + * => | |
| 131 | + return nil; | |
| 132 | + } | |
| 133 | + } | |
| 134 | + return val; | |
| 135 | +} | |
| 136 | +BuildArgList(parms : JArrayJClass, arg : JArrayJObject) : array of ref Value | |
| 137 | +{ | |
| 138 | + # | |
| 139 | + # First do some checking. | |
| 140 | + # | |
| 141 | + l := 0; | |
| 142 | + formal: array of JClass; | |
| 143 | + actual: array of JObject; | |
| 144 | + args: array of ref Value; | |
| 145 | + if ( parms != nil ) { | |
| 146 | + if ( arg == nil ) | |
| 147 | + jni->ThrowException(nullptr, "constructor requires parameters"); | |
| 148 | + if ( len parms.ary != len arg.ary ) | |
| 149 | + jni->ThrowException(illegalarg, "Wrong number of args"); | |
| 150 | + l = len parms.ary; | |
| 151 | + formal = parms.ary; # array of JClass | |
| 152 | + actual = arg.ary; # array of JObject | |
| 153 | + args = array[l] of ref Value; | |
| 154 | + } | |
| 155 | + else # There are no formal parameters | |
| 156 | + if ( arg != nil && len arg.ary != 0 ) # But there are actual arguments | |
| 157 | + jni->ThrowException(illegalarg, "Wrong number of args"); | |
| 158 | + | |
| 159 | + # | |
| 160 | + # March through the arguments, checking for type as we go. | |
| 161 | + # | |
| 162 | + for ( i := 0; i < l; i++ ) { | |
| 163 | + # | |
| 164 | + # Is the formal parameter a primitive? | |
| 165 | + # | |
| 166 | + if ( (want := jni->PrimitiveIndex(formal[i], 1)) > 0 ) { | |
| 167 | + # | |
| 168 | + # Actual parameter should be (derived from) a wrapper, and | |
| 169 | + # be able to be widened to the formal parameter type. | |
| 170 | + # | |
| 171 | + (typ, parmval) := GetVal(actual[i]); | |
| 172 | + if ( (val := widen(want, typ, parmval)) != nil ) | |
| 173 | + args[i] = val; | |
| 174 | + else | |
| 175 | + jni->ThrowException(illegalarg, "Argument " + string (i+1) + | |
| 176 | + ", can't cast"); | |
| 177 | + } | |
| 178 | + else if ( jni->IsInstanceOf(actual[i], formal[i].class) == JNI->TRUE ) { | |
| 179 | + val := ref Value.TObject; | |
| 180 | + val.jobj = actual[i]; | |
| 181 | + args[i] = val; | |
| 182 | + } | |
| 183 | + else | |
| 184 | + jni->ThrowException(illegalarg, "Argument " + string (i+1) + | |
| 185 | + " wrong type"); | |
| 186 | + } | |
| 187 | + return args; | |
| 188 | +} | |
| 189 | +# | |
| 190 | +# Return a JClass corresponding to the Java type t. | |
| 191 | +# | |
| 192 | +Class(t : int) : JClass | |
| 193 | +{ | |
| 194 | + if ( t < T_BOOLEAN || t > T_LONG ) | |
| 195 | + return nil; | |
| 196 | + return jni->GetClassObject(wrapper_class[t - T_BOOLEAN]); | |
| 197 | +} | |
| 198 | +# | |
| 199 | +# Return a Class Object corresponding to the Java type t. | |
| 200 | +# | |
| 201 | +ClassObject(t : int) : JObject | |
| 202 | +{ | |
| 203 | + return cast->FromJClass(Class(t)); | |
| 204 | +} | |
| 205 | +# | |
| 206 | +# Given the java type, get the Class object representing this | |
| 207 | +# type, and return as a Value. | |
| 208 | +# | |
| 209 | +GetPrimitiveClass(typ : int) : ref Value | |
| 210 | +{ | |
| 211 | + return jni->GetStaticField(wrapper_class[typ - T_BOOLEAN], "TYPE", | |
| 212 | + "Ljava/lang/Class;"); | |
| 213 | +} | |
| 214 | +# | |
| 215 | +# If the Object o is a wrapper for a Java primitive type, return the | |
| 216 | +# primitive value (in a Value adt) and the type index. | |
| 217 | +# Otherwise, return 0 and a nil Value. | |
| 218 | +# | |
| 219 | +GetVal(o : JObject) : (int, ref Value) | |
| 220 | +{ | |
| 221 | + j := T_BOOLEAN; | |
| 222 | + for ( i := j; i <= T_LONG; i++ ) { | |
| 223 | + if ( jni->IsInstanceOf(o, wrapper_class[i-j]) == TRUE ) { | |
| 224 | + val := jni->GetObjField(o, "value", type_string[i-j:i-j+1]); | |
| 225 | + return (i, val); | |
| 226 | + } | |
| 227 | + } | |
| 228 | + return (0, nil); | |
| 229 | +} | |
| 230 | +# | |
| 231 | +# Convert a signature to a java type index. | |
| 232 | +# | |
| 233 | +SigToType(sig : string) : int | |
| 234 | +{ | |
| 235 | + index : int; | |
| 236 | + case sig[0] { | |
| 237 | + 'Z' => | |
| 238 | + index = T_BOOLEAN; | |
| 239 | + 'B' => | |
| 240 | + index = T_BYTE; | |
| 241 | + 'C' => | |
| 242 | + index = T_CHAR; | |
| 243 | + 'S' => | |
| 244 | + index = T_SHORT; | |
| 245 | + 'I' => | |
| 246 | + index = T_INT; | |
| 247 | + 'J' => | |
| 248 | + index = T_LONG; | |
| 249 | + 'F' => | |
| 250 | + index = T_FLOAT; | |
| 251 | + 'D' => | |
| 252 | + index = T_DOUBLE; | |
| 253 | + * => | |
| 254 | + index = 0; | |
| 255 | + } | |
| 256 | + return index; | |
| 257 | +} | |
| 258 | +# | |
| 259 | +# Convert a java type index to a signature. | |
| 260 | +# | |
| 261 | +TypeToSig(typ : int) : string | |
| 262 | +{ | |
| 263 | + if ( typ < T_BOOLEAN || typ > T_LONG ) | |
| 264 | + return nil; | |
| 265 | + return type_string[typ-T_BOOLEAN:typ-T_BOOLEAN+1]; | |
| 266 | +} | |
| 267 | +# | |
| 268 | +# Convert a Java type character to its corresponding type name. | |
| 269 | +# | |
| 270 | +TypeCharToName(c : int) : string | |
| 271 | +{ | |
| 272 | + tname : string; | |
| 273 | + case c { | |
| 274 | + 'Z' => | |
| 275 | + tname = "boolean"; | |
| 276 | + 'B' => | |
| 277 | + tname = "byte"; | |
| 278 | + 'C' => | |
| 279 | + tname = "char"; | |
| 280 | + 'S' => | |
| 281 | + tname = "short"; | |
| 282 | + 'I' => | |
| 283 | + tname = "int"; | |
| 284 | + 'J' => | |
| 285 | + tname = "long"; | |
| 286 | + 'F' => | |
| 287 | + tname = "float"; | |
| 288 | + 'D' => | |
| 289 | + tname = "double"; | |
| 290 | + * => | |
| 291 | + tname = "blah"; | |
| 292 | + } | |
| 293 | + return tname; | |
| 294 | +} | |
| 295 | +# | |
| 296 | +# Calculate the type index of the quantity in val. If it isn't a | |
| 297 | +# Java primitive type, return 0; | |
| 298 | +# | |
| 299 | +ValType(val : ref Value) : int | |
| 300 | +{ | |
| 301 | + pick sw := val { | |
| 302 | + TBoolean => return T_BOOLEAN; | |
| 303 | + TByte => return T_BYTE; | |
| 304 | + TChar => return T_CHAR; | |
| 305 | + TShort => return T_SHORT; | |
| 306 | + TInt => return T_INT; | |
| 307 | + TLong => return T_LONG; | |
| 308 | + TFloat => return T_FLOAT; | |
| 309 | + TDouble => return T_DOUBLE; | |
| 310 | + * => return 0; | |
| 311 | + } | |
| 312 | +} | |
| 313 | +# | |
| 314 | +# Create a wrapper Object for the primitive Java value corresponding | |
| 315 | +# to the argument. | |
| 316 | +# | |
| 317 | +ValueToObject(val : ref Value) : JObject | |
| 318 | +{ | |
| 319 | + typ := ValType(val); | |
| 320 | + j := T_BOOLEAN; | |
| 321 | + jobj := jni->AllocObject(wrapper_class[typ - j]); | |
| 322 | + sig := "(" + type_string[typ-j:typ-j+1] + ")V"; | |
| 323 | + (nil, ok) := jni->CallMethod(jobj, "<init>", sig, array[] of { val }); | |
| 324 | + if ( ok == OK ) | |
| 325 | + return jobj; | |
| 326 | + return nil; | |
| 327 | +} | |
| @@ -0,0 +1,19 @@ | ||
| 1 | +Reflect : module { | |
| 2 | + | |
| 3 | + PATH : con "/dis/java/java/java/lang/reflect/reflect.dis"; | |
| 4 | + | |
| 5 | + init : fn(jni_m : JNI); | |
| 6 | + widen : fn(havetype, wanttype : int, val : ref Value) : ref Value; | |
| 7 | + BuildArgList: fn(parms : JArrayJClass, arg : JArrayJObject) | |
| 8 | + : array of ref Value; | |
| 9 | + Class : fn(t : int) : JClass; | |
| 10 | + ClassObject : fn(t : int) : JObject; | |
| 11 | + GetPrimitiveClass : fn(typ : int) : ref Value; | |
| 12 | + GetVal : fn(o : JObject) : (int, ref Value); | |
| 13 | + SigToType : fn(sig : string) : int; | |
| 14 | + TypeToSig : fn(typ : int) : string; | |
| 15 | + TypeCharToName : fn(c : int) : string; | |
| 16 | + ValType : fn(val : ref Value) : int; | |
| 17 | + ValueToObject : fn(val : ref Value) : JObject; | |
| 18 | + | |
| 19 | +}; | |