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 | }; | ||