Print this page
Split |
Close |
Expand all |
Collapse all |
--- old/src/share/classes/java/lang/Class.java
+++ new/src/share/classes/java/lang/Class.java
1 1 /*
2 - * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
2 + * Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved.
3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 4 *
5 5 * This code is free software; you can redistribute it and/or modify it
6 6 * under the terms of the GNU General Public License version 2 only, as
7 7 * published by the Free Software Foundation. Oracle designates this
8 8 * particular file as subject to the "Classpath" exception as provided
9 9 * by Oracle in the LICENSE file that accompanied this code.
10 10 *
11 11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 14 * version 2 for more details (a copy is included in the LICENSE file that
15 15 * accompanied this code).
16 16 *
17 17 * You should have received a copy of the GNU General Public License version
18 18 * 2 along with this work; if not, write to the Free Software Foundation,
19 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 20 *
21 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 22 * or visit www.oracle.com if you need additional information or have any
23 23 * questions.
24 24 */
25 25
26 26 package java.lang;
27 27
28 28 import java.lang.reflect.Array;
29 29 import java.lang.reflect.GenericArrayType;
30 30 import java.lang.reflect.Member;
31 31 import java.lang.reflect.Field;
32 32 import java.lang.reflect.Method;
33 33 import java.lang.reflect.Constructor;
34 34 import java.lang.reflect.Modifier;
35 35 import java.lang.reflect.Type;
36 36 import java.lang.reflect.TypeVariable;
37 37 import java.lang.reflect.InvocationTargetException;
38 38 import java.lang.ref.SoftReference;
39 39 import java.io.InputStream;
40 40 import java.io.ObjectStreamField;
41 41 import java.security.AccessController;
42 42 import java.security.PrivilegedAction;
43 43 import java.util.ArrayList;
44 44 import java.util.Arrays;
45 45 import java.util.Collection;
46 46 import java.util.HashSet;
47 47 import java.util.List;
48 48 import java.util.Set;
49 49 import java.util.Map;
50 50 import java.util.HashMap;
51 51 import sun.misc.Unsafe;
52 52 import sun.reflect.ConstantPool;
53 53 import sun.reflect.Reflection;
54 54 import sun.reflect.ReflectionFactory;
55 55 import sun.reflect.generics.factory.CoreReflectionFactory;
56 56 import sun.reflect.generics.factory.GenericsFactory;
57 57 import sun.reflect.generics.repository.ClassRepository;
58 58 import sun.reflect.generics.repository.MethodRepository;
59 59 import sun.reflect.generics.repository.ConstructorRepository;
60 60 import sun.reflect.generics.scope.ClassScope;
61 61 import sun.security.util.SecurityConstants;
62 62 import java.lang.annotation.Annotation;
63 63 import sun.reflect.annotation.*;
64 64
65 65 /**
66 66 * Instances of the class {@code Class} represent classes and
67 67 * interfaces in a running Java application. An enum is a kind of
68 68 * class and an annotation is a kind of interface. Every array also
69 69 * belongs to a class that is reflected as a {@code Class} object
70 70 * that is shared by all arrays with the same element type and number
71 71 * of dimensions. The primitive Java types ({@code boolean},
72 72 * {@code byte}, {@code char}, {@code short},
73 73 * {@code int}, {@code long}, {@code float}, and
74 74 * {@code double}), and the keyword {@code void} are also
75 75 * represented as {@code Class} objects.
76 76 *
77 77 * <p> {@code Class} has no public constructor. Instead {@code Class}
78 78 * objects are constructed automatically by the Java Virtual Machine as classes
79 79 * are loaded and by calls to the {@code defineClass} method in the class
80 80 * loader.
81 81 *
82 82 * <p> The following example uses a {@code Class} object to print the
83 83 * class name of an object:
84 84 *
85 85 * <p> <blockquote><pre>
86 86 * void printClassName(Object obj) {
87 87 * System.out.println("The class of " + obj +
88 88 * " is " + obj.getClass().getName());
89 89 * }
90 90 * </pre></blockquote>
91 91 *
92 92 * <p> It is also possible to get the {@code Class} object for a named
93 93 * type (or for void) using a class literal. See Section 15.8.2 of
94 94 * <cite>The Java™ Language Specification</cite>.
95 95 * For example:
96 96 *
97 97 * <p> <blockquote>
98 98 * {@code System.out.println("The name of class Foo is: "+Foo.class.getName());}
99 99 * </blockquote>
100 100 *
↓ open down ↓ |
88 lines elided |
↑ open up ↑ |
101 101 * @param <T> the type of the class modeled by this {@code Class}
102 102 * object. For example, the type of {@code String.class} is {@code
103 103 * Class<String>}. Use {@code Class<?>} if the class being modeled is
104 104 * unknown.
105 105 *
106 106 * @author unascribed
107 107 * @see java.lang.ClassLoader#defineClass(byte[], int, int)
108 108 * @since JDK1.0
109 109 */
110 110 public final
111 - class Class<T> implements java.io.Serializable,
112 - java.lang.reflect.GenericDeclaration,
113 - java.lang.reflect.Type,
114 - java.lang.reflect.AnnotatedElement {
111 + class Class<T> implements java.io.Serializable,
112 + java.lang.reflect.GenericDeclaration,
113 + java.lang.reflect.Type,
114 + java.lang.reflect.AnnotatedElement {
115 115 private static final int ANNOTATION= 0x00002000;
116 116 private static final int ENUM = 0x00004000;
117 117 private static final int SYNTHETIC = 0x00001000;
118 -
118 +
119 119 private static native void registerNatives();
120 120 static {
121 121 registerNatives();
122 122 }
123 123
124 124 /*
125 125 * Constructor. Only the Java Virtual Machine creates Class
126 126 * objects.
127 127 */
128 128 private Class() {}
129 129
130 130
131 131 /**
132 132 * Converts the object to a string. The string representation is the
133 133 * string "class" or "interface", followed by a space, and then by the
134 134 * fully qualified name of the class in the format returned by
135 135 * {@code getName}. If this {@code Class} object represents a
136 136 * primitive type, this method returns the name of the primitive type. If
137 137 * this {@code Class} object represents void this method returns
138 138 * "void".
139 139 *
140 140 * @return a string representation of this class object.
141 141 */
142 142 public String toString() {
143 143 return (isInterface() ? "interface " : (isPrimitive() ? "" : "class "))
144 144 + getName();
145 145 }
146 146
147 147
148 148 /**
149 149 * Returns the {@code Class} object associated with the class or
150 150 * interface with the given string name. Invoking this method is
151 151 * equivalent to:
152 152 *
153 153 * <blockquote>
154 154 * {@code Class.forName(className, true, currentLoader)}
155 155 * </blockquote>
156 156 *
157 157 * where {@code currentLoader} denotes the defining class loader of
158 158 * the current class.
159 159 *
160 160 * <p> For example, the following code fragment returns the
161 161 * runtime {@code Class} descriptor for the class named
162 162 * {@code java.lang.Thread}:
163 163 *
164 164 * <blockquote>
165 165 * {@code Class t = Class.forName("java.lang.Thread")}
166 166 * </blockquote>
167 167 * <p>
168 168 * A call to {@code forName("X")} causes the class named
169 169 * {@code X} to be initialized.
170 170 *
171 171 * @param className the fully qualified name of the desired class.
172 172 * @return the {@code Class} object for the class with the
173 173 * specified name.
174 174 * @exception LinkageError if the linkage fails
175 175 * @exception ExceptionInInitializerError if the initialization provoked
176 176 * by this method fails
177 177 * @exception ClassNotFoundException if the class cannot be located
178 178 */
179 179 public static Class<?> forName(String className)
180 180 throws ClassNotFoundException {
181 181 return forName0(className, true, ClassLoader.getCallerClassLoader());
182 182 }
183 183
184 184
185 185 /**
186 186 * Returns the {@code Class} object associated with the class or
187 187 * interface with the given string name, using the given class loader.
188 188 * Given the fully qualified name for a class or interface (in the same
189 189 * format returned by {@code getName}) this method attempts to
190 190 * locate, load, and link the class or interface. The specified class
191 191 * loader is used to load the class or interface. If the parameter
192 192 * {@code loader} is null, the class is loaded through the bootstrap
193 193 * class loader. The class is initialized only if the
194 194 * {@code initialize} parameter is {@code true} and if it has
195 195 * not been initialized earlier.
196 196 *
197 197 * <p> If {@code name} denotes a primitive type or void, an attempt
198 198 * will be made to locate a user-defined class in the unnamed package whose
199 199 * name is {@code name}. Therefore, this method cannot be used to
200 200 * obtain any of the {@code Class} objects representing primitive
201 201 * types or void.
202 202 *
203 203 * <p> If {@code name} denotes an array class, the component type of
204 204 * the array class is loaded but not initialized.
205 205 *
206 206 * <p> For example, in an instance method the expression:
207 207 *
208 208 * <blockquote>
209 209 * {@code Class.forName("Foo")}
210 210 * </blockquote>
211 211 *
212 212 * is equivalent to:
213 213 *
214 214 * <blockquote>
215 215 * {@code Class.forName("Foo", true, this.getClass().getClassLoader())}
216 216 * </blockquote>
217 217 *
218 218 * Note that this method throws errors related to loading, linking or
219 219 * initializing as specified in Sections 12.2, 12.3 and 12.4 of <em>The
220 220 * Java Language Specification</em>.
221 221 * Note that this method does not check whether the requested class
222 222 * is accessible to its caller.
223 223 *
224 224 * <p> If the {@code loader} is {@code null}, and a security
225 225 * manager is present, and the caller's class loader is not null, then this
226 226 * method calls the security manager's {@code checkPermission} method
227 227 * with a {@code RuntimePermission("getClassLoader")} permission to
228 228 * ensure it's ok to access the bootstrap class loader.
229 229 *
230 230 * @param name fully qualified name of the desired class
231 231 * @param initialize whether the class must be initialized
232 232 * @param loader class loader from which the class must be loaded
233 233 * @return class object representing the desired class
234 234 *
235 235 * @exception LinkageError if the linkage fails
236 236 * @exception ExceptionInInitializerError if the initialization provoked
237 237 * by this method fails
238 238 * @exception ClassNotFoundException if the class cannot be located by
239 239 * the specified class loader
240 240 *
241 241 * @see java.lang.Class#forName(String)
242 242 * @see java.lang.ClassLoader
243 243 * @since 1.2
244 244 */
245 245 public static Class<?> forName(String name, boolean initialize,
246 246 ClassLoader loader)
247 247 throws ClassNotFoundException
248 248 {
249 249 if (loader == null) {
250 250 SecurityManager sm = System.getSecurityManager();
251 251 if (sm != null) {
252 252 ClassLoader ccl = ClassLoader.getCallerClassLoader();
253 253 if (ccl != null) {
254 254 sm.checkPermission(
255 255 SecurityConstants.GET_CLASSLOADER_PERMISSION);
256 256 }
257 257 }
258 258 }
259 259 return forName0(name, initialize, loader);
260 260 }
261 261
262 262 /** Called after security checks have been made. */
263 263 private static native Class<?> forName0(String name, boolean initialize,
264 264 ClassLoader loader)
265 265 throws ClassNotFoundException;
266 266
267 267 /**
268 268 * Creates a new instance of the class represented by this {@code Class}
269 269 * object. The class is instantiated as if by a {@code new}
270 270 * expression with an empty argument list. The class is initialized if it
271 271 * has not already been initialized.
272 272 *
273 273 * <p>Note that this method propagates any exception thrown by the
274 274 * nullary constructor, including a checked exception. Use of
275 275 * this method effectively bypasses the compile-time exception
276 276 * checking that would otherwise be performed by the compiler.
277 277 * The {@link
278 278 * java.lang.reflect.Constructor#newInstance(java.lang.Object...)
279 279 * Constructor.newInstance} method avoids this problem by wrapping
280 280 * any exception thrown by the constructor in a (checked) {@link
281 281 * java.lang.reflect.InvocationTargetException}.
282 282 *
283 283 * @return a newly allocated instance of the class represented by this
284 284 * object.
285 285 * @exception IllegalAccessException if the class or its nullary
286 286 * constructor is not accessible.
287 287 * @exception InstantiationException
288 288 * if this {@code Class} represents an abstract class,
289 289 * an interface, an array class, a primitive type, or void;
290 290 * or if the class has no nullary constructor;
291 291 * or if the instantiation fails for some other reason.
292 292 * @exception ExceptionInInitializerError if the initialization
293 293 * provoked by this method fails.
294 294 * @exception SecurityException
295 295 * If a security manager, <i>s</i>, is present and any of the
296 296 * following conditions is met:
297 297 *
298 298 * <ul>
299 299 *
300 300 * <li> invocation of
301 301 * {@link SecurityManager#checkMemberAccess
302 302 * s.checkMemberAccess(this, Member.PUBLIC)} denies
303 303 * creation of new instances of this class
304 304 *
305 305 * <li> the caller's class loader is not the same as or an
306 306 * ancestor of the class loader for the current class and
307 307 * invocation of {@link SecurityManager#checkPackageAccess
308 308 * s.checkPackageAccess()} denies access to the package
309 309 * of this class
310 310 *
311 311 * </ul>
312 312 *
313 313 */
314 314 public T newInstance()
315 315 throws InstantiationException, IllegalAccessException
316 316 {
317 317 if (System.getSecurityManager() != null) {
318 318 checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
319 319 }
↓ open down ↓ |
191 lines elided |
↑ open up ↑ |
320 320 return newInstance0();
321 321 }
322 322
323 323 private T newInstance0()
324 324 throws InstantiationException, IllegalAccessException
325 325 {
326 326 // NOTE: the following code may not be strictly correct under
327 327 // the current Java memory model.
328 328
329 329 // Constructor lookup
330 - if (cachedConstructor == null) {
330 + final ReflectionHelper rh = rh();
331 + if (rh.cachedConstructor == null) {
331 332 if (this == Class.class) {
332 333 throw new IllegalAccessException(
333 334 "Can not call newInstance() on the Class for java.lang.Class"
334 335 );
335 336 }
336 337 try {
337 338 Class<?>[] empty = {};
338 339 final Constructor<T> c = getConstructor0(empty, Member.DECLARED);
339 340 // Disable accessibility checks on the constructor
340 341 // since we have to do the security check here anyway
341 342 // (the stack depth is wrong for the Constructor's
342 343 // security check to work)
343 344 java.security.AccessController.doPrivileged(
344 345 new java.security.PrivilegedAction<Void>() {
345 346 public Void run() {
346 347 c.setAccessible(true);
347 348 return null;
348 349 }
349 350 });
350 - cachedConstructor = c;
351 + rh.cachedConstructor = c;
351 352 } catch (NoSuchMethodException e) {
352 353 throw (InstantiationException)
353 354 new InstantiationException(getName()).initCause(e);
354 355 }
355 356 }
356 - Constructor<T> tmpConstructor = cachedConstructor;
357 + Constructor<T> tmpConstructor = rh.cachedConstructor;
357 358 // Security check (same as in java.lang.reflect.Constructor)
358 359 int modifiers = tmpConstructor.getModifiers();
359 360 if (!Reflection.quickCheckMemberAccess(this, modifiers)) {
360 361 Class<?> caller = Reflection.getCallerClass(3);
361 - if (newInstanceCallerCache != caller) {
362 + if (rh.newInstanceCallerCache != caller) {
362 363 Reflection.ensureMemberAccess(caller, this, null, modifiers);
363 - newInstanceCallerCache = caller;
364 + rh.newInstanceCallerCache = caller;
364 365 }
365 366 }
366 367 // Run constructor
367 368 try {
368 369 return tmpConstructor.newInstance((Object[])null);
369 370 } catch (InvocationTargetException e) {
370 371 Unsafe.getUnsafe().throwException(e.getTargetException());
371 372 // Not reached
372 373 return null;
373 374 }
374 375 }
375 - private volatile transient Constructor<T> cachedConstructor;
376 - private volatile transient Class<?> newInstanceCallerCache;
377 376
378 377
379 378 /**
380 379 * Determines if the specified {@code Object} is assignment-compatible
381 380 * with the object represented by this {@code Class}. This method is
382 381 * the dynamic equivalent of the Java language {@code instanceof}
383 382 * operator. The method returns {@code true} if the specified
384 383 * {@code Object} argument is non-null and can be cast to the
385 384 * reference type represented by this {@code Class} object without
386 385 * raising a {@code ClassCastException.} It returns {@code false}
387 386 * otherwise.
388 387 *
389 388 * <p> Specifically, if this {@code Class} object represents a
390 389 * declared class, this method returns {@code true} if the specified
391 390 * {@code Object} argument is an instance of the represented class (or
392 391 * of any of its subclasses); it returns {@code false} otherwise. If
393 392 * this {@code Class} object represents an array class, this method
394 393 * returns {@code true} if the specified {@code Object} argument
395 394 * can be converted to an object of the array class by an identity
396 395 * conversion or by a widening reference conversion; it returns
397 396 * {@code false} otherwise. If this {@code Class} object
398 397 * represents an interface, this method returns {@code true} if the
399 398 * class or any superclass of the specified {@code Object} argument
400 399 * implements this interface; it returns {@code false} otherwise. If
401 400 * this {@code Class} object represents a primitive type, this method
402 401 * returns {@code false}.
403 402 *
404 403 * @param obj the object to check
405 404 * @return true if {@code obj} is an instance of this class
406 405 *
407 406 * @since JDK1.1
408 407 */
409 408 public native boolean isInstance(Object obj);
410 409
411 410
412 411 /**
413 412 * Determines if the class or interface represented by this
414 413 * {@code Class} object is either the same as, or is a superclass or
415 414 * superinterface of, the class or interface represented by the specified
416 415 * {@code Class} parameter. It returns {@code true} if so;
417 416 * otherwise it returns {@code false}. If this {@code Class}
418 417 * object represents a primitive type, this method returns
419 418 * {@code true} if the specified {@code Class} parameter is
420 419 * exactly this {@code Class} object; otherwise it returns
421 420 * {@code false}.
422 421 *
423 422 * <p> Specifically, this method tests whether the type represented by the
424 423 * specified {@code Class} parameter can be converted to the type
425 424 * represented by this {@code Class} object via an identity conversion
426 425 * or via a widening reference conversion. See <em>The Java Language
427 426 * Specification</em>, sections 5.1.1 and 5.1.4 , for details.
428 427 *
429 428 * @param cls the {@code Class} object to be checked
430 429 * @return the {@code boolean} value indicating whether objects of the
431 430 * type {@code cls} can be assigned to objects of this class
432 431 * @exception NullPointerException if the specified Class parameter is
433 432 * null.
434 433 * @since JDK1.1
435 434 */
436 435 public native boolean isAssignableFrom(Class<?> cls);
437 436
438 437
439 438 /**
440 439 * Determines if the specified {@code Class} object represents an
441 440 * interface type.
442 441 *
443 442 * @return {@code true} if this object represents an interface;
444 443 * {@code false} otherwise.
445 444 */
446 445 public native boolean isInterface();
447 446
448 447
449 448 /**
450 449 * Determines if this {@code Class} object represents an array class.
451 450 *
452 451 * @return {@code true} if this object represents an array class;
453 452 * {@code false} otherwise.
454 453 * @since JDK1.1
455 454 */
456 455 public native boolean isArray();
457 456
458 457
459 458 /**
460 459 * Determines if the specified {@code Class} object represents a
461 460 * primitive type.
462 461 *
463 462 * <p> There are nine predefined {@code Class} objects to represent
464 463 * the eight primitive types and void. These are created by the Java
465 464 * Virtual Machine, and have the same names as the primitive types that
466 465 * they represent, namely {@code boolean}, {@code byte},
467 466 * {@code char}, {@code short}, {@code int},
468 467 * {@code long}, {@code float}, and {@code double}.
469 468 *
470 469 * <p> These objects may only be accessed via the following public static
471 470 * final variables, and are the only {@code Class} objects for which
472 471 * this method returns {@code true}.
473 472 *
474 473 * @return true if and only if this class represents a primitive type
475 474 *
476 475 * @see java.lang.Boolean#TYPE
477 476 * @see java.lang.Character#TYPE
478 477 * @see java.lang.Byte#TYPE
479 478 * @see java.lang.Short#TYPE
480 479 * @see java.lang.Integer#TYPE
481 480 * @see java.lang.Long#TYPE
482 481 * @see java.lang.Float#TYPE
483 482 * @see java.lang.Double#TYPE
484 483 * @see java.lang.Void#TYPE
485 484 * @since JDK1.1
486 485 */
487 486 public native boolean isPrimitive();
488 487
489 488 /**
490 489 * Returns true if this {@code Class} object represents an annotation
491 490 * type. Note that if this method returns true, {@link #isInterface()}
492 491 * would also return true, as all annotation types are also interfaces.
493 492 *
494 493 * @return {@code true} if this class object represents an annotation
495 494 * type; {@code false} otherwise
496 495 * @since 1.5
497 496 */
498 497 public boolean isAnnotation() {
499 498 return (getModifiers() & ANNOTATION) != 0;
500 499 }
501 500
502 501 /**
503 502 * Returns {@code true} if this class is a synthetic class;
504 503 * returns {@code false} otherwise.
505 504 * @return {@code true} if and only if this class is a synthetic class as
506 505 * defined by the Java Language Specification.
507 506 * @since 1.5
508 507 */
509 508 public boolean isSynthetic() {
510 509 return (getModifiers() & SYNTHETIC) != 0;
511 510 }
512 511
513 512 /**
514 513 * Returns the name of the entity (class, interface, array class,
515 514 * primitive type, or void) represented by this {@code Class} object,
516 515 * as a {@code String}.
517 516 *
518 517 * <p> If this class object represents a reference type that is not an
519 518 * array type then the binary name of the class is returned, as specified
520 519 * by
521 520 * <cite>The Java™ Language Specification</cite>.
522 521 *
523 522 * <p> If this class object represents a primitive type or void, then the
524 523 * name returned is a {@code String} equal to the Java language
525 524 * keyword corresponding to the primitive type or void.
526 525 *
527 526 * <p> If this class object represents a class of arrays, then the internal
528 527 * form of the name consists of the name of the element type preceded by
529 528 * one or more '{@code [}' characters representing the depth of the array
530 529 * nesting. The encoding of element type names is as follows:
531 530 *
532 531 * <blockquote><table summary="Element types and encodings">
533 532 * <tr><th> Element Type <th> <th> Encoding
534 533 * <tr><td> boolean <td> <td align=center> Z
535 534 * <tr><td> byte <td> <td align=center> B
536 535 * <tr><td> char <td> <td align=center> C
537 536 * <tr><td> class or interface
538 537 * <td> <td align=center> L<i>classname</i>;
539 538 * <tr><td> double <td> <td align=center> D
540 539 * <tr><td> float <td> <td align=center> F
541 540 * <tr><td> int <td> <td align=center> I
542 541 * <tr><td> long <td> <td align=center> J
543 542 * <tr><td> short <td> <td align=center> S
544 543 * </table></blockquote>
545 544 *
546 545 * <p> The class or interface name <i>classname</i> is the binary name of
547 546 * the class specified above.
548 547 *
549 548 * <p> Examples:
550 549 * <blockquote><pre>
551 550 * String.class.getName()
552 551 * returns "java.lang.String"
553 552 * byte.class.getName()
554 553 * returns "byte"
555 554 * (new Object[3]).getClass().getName()
556 555 * returns "[Ljava.lang.Object;"
557 556 * (new int[3][4][5][6][7][8][9]).getClass().getName()
558 557 * returns "[[[[[[[I"
559 558 * </pre></blockquote>
560 559 *
561 560 * @return the name of the class or interface
562 561 * represented by this object.
563 562 */
564 563 public String getName() {
565 564 String name = this.name;
566 565 if (name == null)
567 566 this.name = name = getName0();
568 567 return name;
569 568 }
570 569
571 570 // cache the name to reduce the number of calls into the VM
572 571 private transient String name;
573 572 private native String getName0();
574 573
575 574 /**
576 575 * Returns the class loader for the class. Some implementations may use
577 576 * null to represent the bootstrap class loader. This method will return
578 577 * null in such implementations if this class was loaded by the bootstrap
579 578 * class loader.
580 579 *
581 580 * <p> If a security manager is present, and the caller's class loader is
582 581 * not null and the caller's class loader is not the same as or an ancestor of
583 582 * the class loader for the class whose class loader is requested, then
584 583 * this method calls the security manager's {@code checkPermission}
585 584 * method with a {@code RuntimePermission("getClassLoader")}
586 585 * permission to ensure it's ok to access the class loader for the class.
587 586 *
588 587 * <p>If this object
589 588 * represents a primitive type or void, null is returned.
590 589 *
591 590 * @return the class loader that loaded the class or interface
592 591 * represented by this object.
593 592 * @throws SecurityException
594 593 * if a security manager exists and its
595 594 * {@code checkPermission} method denies
596 595 * access to the class loader for the class.
597 596 * @see java.lang.ClassLoader
598 597 * @see SecurityManager#checkPermission
599 598 * @see java.lang.RuntimePermission
600 599 */
601 600 public ClassLoader getClassLoader() {
602 601 ClassLoader cl = getClassLoader0();
603 602 if (cl == null)
604 603 return null;
605 604 SecurityManager sm = System.getSecurityManager();
606 605 if (sm != null) {
607 606 ClassLoader ccl = ClassLoader.getCallerClassLoader();
608 607 if (ccl != null && ccl != cl && !cl.isAncestor(ccl)) {
609 608 sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
610 609 }
611 610 }
612 611 return cl;
613 612 }
614 613
615 614 // Package-private to allow ClassLoader access
616 615 native ClassLoader getClassLoader0();
617 616
618 617
619 618 /**
620 619 * Returns an array of {@code TypeVariable} objects that represent the
621 620 * type variables declared by the generic declaration represented by this
622 621 * {@code GenericDeclaration} object, in declaration order. Returns an
623 622 * array of length 0 if the underlying generic declaration declares no type
624 623 * variables.
625 624 *
626 625 * @return an array of {@code TypeVariable} objects that represent
627 626 * the type variables declared by this generic declaration
628 627 * @throws java.lang.reflect.GenericSignatureFormatError if the generic
629 628 * signature of this generic declaration does not conform to
630 629 * the format specified in
631 630 * <cite>The Java™ Virtual Machine Specification</cite>
632 631 * @since 1.5
633 632 */
634 633 @SuppressWarnings("unchecked")
635 634 public TypeVariable<Class<T>>[] getTypeParameters() {
636 635 if (getGenericSignature() != null)
637 636 return (TypeVariable<Class<T>>[])getGenericInfo().getTypeParameters();
638 637 else
639 638 return (TypeVariable<Class<T>>[])new TypeVariable<?>[0];
640 639 }
641 640
642 641
643 642 /**
644 643 * Returns the {@code Class} representing the superclass of the entity
645 644 * (class, interface, primitive type or void) represented by this
646 645 * {@code Class}. If this {@code Class} represents either the
647 646 * {@code Object} class, an interface, a primitive type, or void, then
648 647 * null is returned. If this object represents an array class then the
649 648 * {@code Class} object representing the {@code Object} class is
650 649 * returned.
651 650 *
652 651 * @return the superclass of the class represented by this object.
653 652 */
654 653 public native Class<? super T> getSuperclass();
655 654
656 655
657 656 /**
658 657 * Returns the {@code Type} representing the direct superclass of
659 658 * the entity (class, interface, primitive type or void) represented by
660 659 * this {@code Class}.
661 660 *
662 661 * <p>If the superclass is a parameterized type, the {@code Type}
663 662 * object returned must accurately reflect the actual type
664 663 * parameters used in the source code. The parameterized type
665 664 * representing the superclass is created if it had not been
666 665 * created before. See the declaration of {@link
667 666 * java.lang.reflect.ParameterizedType ParameterizedType} for the
668 667 * semantics of the creation process for parameterized types. If
669 668 * this {@code Class} represents either the {@code Object}
670 669 * class, an interface, a primitive type, or void, then null is
671 670 * returned. If this object represents an array class then the
672 671 * {@code Class} object representing the {@code Object} class is
673 672 * returned.
674 673 *
675 674 * @throws java.lang.reflect.GenericSignatureFormatError if the generic
676 675 * class signature does not conform to the format specified in
677 676 * <cite>The Java™ Virtual Machine Specification</cite>
678 677 * @throws TypeNotPresentException if the generic superclass
679 678 * refers to a non-existent type declaration
680 679 * @throws java.lang.reflect.MalformedParameterizedTypeException if the
681 680 * generic superclass refers to a parameterized type that cannot be
682 681 * instantiated for any reason
683 682 * @return the superclass of the class represented by this object
684 683 * @since 1.5
685 684 */
686 685 public Type getGenericSuperclass() {
687 686 if (getGenericSignature() != null) {
688 687 // Historical irregularity:
689 688 // Generic signature marks interfaces with superclass = Object
690 689 // but this API returns null for interfaces
691 690 if (isInterface())
692 691 return null;
693 692 return getGenericInfo().getSuperclass();
694 693 } else
695 694 return getSuperclass();
696 695 }
697 696
698 697 /**
699 698 * Gets the package for this class. The class loader of this class is used
700 699 * to find the package. If the class was loaded by the bootstrap class
701 700 * loader the set of packages loaded from CLASSPATH is searched to find the
702 701 * package of the class. Null is returned if no package object was created
703 702 * by the class loader of this class.
704 703 *
705 704 * <p> Packages have attributes for versions and specifications only if the
706 705 * information was defined in the manifests that accompany the classes, and
707 706 * if the class loader created the package instance with the attributes
708 707 * from the manifest.
709 708 *
710 709 * @return the package of the class, or null if no package
711 710 * information is available from the archive or codebase.
712 711 */
713 712 public Package getPackage() {
714 713 return Package.getPackage(this);
715 714 }
716 715
717 716
718 717 /**
719 718 * Determines the interfaces implemented by the class or interface
720 719 * represented by this object.
721 720 *
722 721 * <p> If this object represents a class, the return value is an array
723 722 * containing objects representing all interfaces implemented by the
724 723 * class. The order of the interface objects in the array corresponds to
725 724 * the order of the interface names in the {@code implements} clause
726 725 * of the declaration of the class represented by this object. For
727 726 * example, given the declaration:
728 727 * <blockquote>
729 728 * {@code class Shimmer implements FloorWax, DessertTopping { ... }}
730 729 * </blockquote>
731 730 * suppose the value of {@code s} is an instance of
732 731 * {@code Shimmer}; the value of the expression:
733 732 * <blockquote>
734 733 * {@code s.getClass().getInterfaces()[0]}
735 734 * </blockquote>
736 735 * is the {@code Class} object that represents interface
737 736 * {@code FloorWax}; and the value of:
738 737 * <blockquote>
739 738 * {@code s.getClass().getInterfaces()[1]}
740 739 * </blockquote>
741 740 * is the {@code Class} object that represents interface
742 741 * {@code DessertTopping}.
743 742 *
744 743 * <p> If this object represents an interface, the array contains objects
745 744 * representing all interfaces extended by the interface. The order of the
746 745 * interface objects in the array corresponds to the order of the interface
747 746 * names in the {@code extends} clause of the declaration of the
748 747 * interface represented by this object.
749 748 *
750 749 * <p> If this object represents a class or interface that implements no
751 750 * interfaces, the method returns an array of length 0.
752 751 *
753 752 * <p> If this object represents a primitive type or void, the method
754 753 * returns an array of length 0.
755 754 *
756 755 * @return an array of interfaces implemented by this class.
757 756 */
758 757 public native Class<?>[] getInterfaces();
759 758
760 759 /**
761 760 * Returns the {@code Type}s representing the interfaces
762 761 * directly implemented by the class or interface represented by
763 762 * this object.
764 763 *
765 764 * <p>If a superinterface is a parameterized type, the
766 765 * {@code Type} object returned for it must accurately reflect
767 766 * the actual type parameters used in the source code. The
768 767 * parameterized type representing each superinterface is created
769 768 * if it had not been created before. See the declaration of
770 769 * {@link java.lang.reflect.ParameterizedType ParameterizedType}
771 770 * for the semantics of the creation process for parameterized
772 771 * types.
773 772 *
774 773 * <p> If this object represents a class, the return value is an
775 774 * array containing objects representing all interfaces
776 775 * implemented by the class. The order of the interface objects in
777 776 * the array corresponds to the order of the interface names in
778 777 * the {@code implements} clause of the declaration of the class
779 778 * represented by this object. In the case of an array class, the
780 779 * interfaces {@code Cloneable} and {@code Serializable} are
781 780 * returned in that order.
782 781 *
783 782 * <p>If this object represents an interface, the array contains
784 783 * objects representing all interfaces directly extended by the
785 784 * interface. The order of the interface objects in the array
786 785 * corresponds to the order of the interface names in the
787 786 * {@code extends} clause of the declaration of the interface
788 787 * represented by this object.
789 788 *
790 789 * <p>If this object represents a class or interface that
791 790 * implements no interfaces, the method returns an array of length
792 791 * 0.
793 792 *
794 793 * <p>If this object represents a primitive type or void, the
795 794 * method returns an array of length 0.
796 795 *
797 796 * @throws java.lang.reflect.GenericSignatureFormatError
798 797 * if the generic class signature does not conform to the format
799 798 * specified in
800 799 * <cite>The Java™ Virtual Machine Specification</cite>
801 800 * @throws TypeNotPresentException if any of the generic
802 801 * superinterfaces refers to a non-existent type declaration
803 802 * @throws java.lang.reflect.MalformedParameterizedTypeException
804 803 * if any of the generic superinterfaces refer to a parameterized
805 804 * type that cannot be instantiated for any reason
806 805 * @return an array of interfaces implemented by this class
807 806 * @since 1.5
808 807 */
809 808 public Type[] getGenericInterfaces() {
810 809 if (getGenericSignature() != null)
811 810 return getGenericInfo().getSuperInterfaces();
812 811 else
813 812 return getInterfaces();
814 813 }
815 814
816 815
817 816 /**
818 817 * Returns the {@code Class} representing the component type of an
819 818 * array. If this class does not represent an array class this method
820 819 * returns null.
821 820 *
822 821 * @return the {@code Class} representing the component type of this
823 822 * class if this class is an array
824 823 * @see java.lang.reflect.Array
825 824 * @since JDK1.1
826 825 */
827 826 public native Class<?> getComponentType();
828 827
829 828
830 829 /**
831 830 * Returns the Java language modifiers for this class or interface, encoded
832 831 * in an integer. The modifiers consist of the Java Virtual Machine's
833 832 * constants for {@code public}, {@code protected},
834 833 * {@code private}, {@code final}, {@code static},
835 834 * {@code abstract} and {@code interface}; they should be decoded
836 835 * using the methods of class {@code Modifier}.
837 836 *
838 837 * <p> If the underlying class is an array class, then its
839 838 * {@code public}, {@code private} and {@code protected}
840 839 * modifiers are the same as those of its component type. If this
841 840 * {@code Class} represents a primitive type or void, its
842 841 * {@code public} modifier is always {@code true}, and its
843 842 * {@code protected} and {@code private} modifiers are always
844 843 * {@code false}. If this object represents an array class, a
845 844 * primitive type or void, then its {@code final} modifier is always
846 845 * {@code true} and its interface modifier is always
847 846 * {@code false}. The values of its other modifiers are not determined
848 847 * by this specification.
849 848 *
850 849 * <p> The modifier encodings are defined in <em>The Java Virtual Machine
851 850 * Specification</em>, table 4.1.
852 851 *
853 852 * @return the {@code int} representing the modifiers for this class
854 853 * @see java.lang.reflect.Modifier
855 854 * @since JDK1.1
856 855 */
857 856 public native int getModifiers();
858 857
859 858
860 859 /**
861 860 * Gets the signers of this class.
862 861 *
863 862 * @return the signers of this class, or null if there are no signers. In
864 863 * particular, this method returns null if this object represents
865 864 * a primitive type or void.
866 865 * @since JDK1.1
867 866 */
868 867 public native Object[] getSigners();
869 868
870 869
871 870 /**
872 871 * Set the signers of this class.
873 872 */
874 873 native void setSigners(Object[] signers);
875 874
876 875
877 876 /**
878 877 * If this {@code Class} object represents a local or anonymous
879 878 * class within a method, returns a {@link
880 879 * java.lang.reflect.Method Method} object representing the
881 880 * immediately enclosing method of the underlying class. Returns
882 881 * {@code null} otherwise.
883 882 *
884 883 * In particular, this method returns {@code null} if the underlying
885 884 * class is a local or anonymous class immediately enclosed by a type
886 885 * declaration, instance initializer or static initializer.
887 886 *
888 887 * @return the immediately enclosing method of the underlying class, if
889 888 * that class is a local or anonymous class; otherwise {@code null}.
890 889 * @since 1.5
891 890 */
892 891 public Method getEnclosingMethod() {
893 892 EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
894 893
895 894 if (enclosingInfo == null)
896 895 return null;
897 896 else {
898 897 if (!enclosingInfo.isMethod())
899 898 return null;
900 899
901 900 MethodRepository typeInfo = MethodRepository.make(enclosingInfo.getDescriptor(),
902 901 getFactory());
903 902 Class<?> returnType = toClass(typeInfo.getReturnType());
904 903 Type [] parameterTypes = typeInfo.getParameterTypes();
905 904 Class<?>[] parameterClasses = new Class<?>[parameterTypes.length];
906 905
907 906 // Convert Types to Classes; returned types *should*
908 907 // be class objects since the methodDescriptor's used
909 908 // don't have generics information
910 909 for(int i = 0; i < parameterClasses.length; i++)
911 910 parameterClasses[i] = toClass(parameterTypes[i]);
912 911
913 912 /*
914 913 * Loop over all declared methods; match method name,
915 914 * number of and type of parameters, *and* return
916 915 * type. Matching return type is also necessary
917 916 * because of covariant returns, etc.
918 917 */
919 918 for(Method m: enclosingInfo.getEnclosingClass().getDeclaredMethods()) {
920 919 if (m.getName().equals(enclosingInfo.getName()) ) {
921 920 Class<?>[] candidateParamClasses = m.getParameterTypes();
922 921 if (candidateParamClasses.length == parameterClasses.length) {
923 922 boolean matches = true;
924 923 for(int i = 0; i < candidateParamClasses.length; i++) {
925 924 if (!candidateParamClasses[i].equals(parameterClasses[i])) {
926 925 matches = false;
927 926 break;
928 927 }
929 928 }
930 929
931 930 if (matches) { // finally, check return type
932 931 if (m.getReturnType().equals(returnType) )
933 932 return m;
934 933 }
935 934 }
936 935 }
937 936 }
938 937
939 938 throw new InternalError("Enclosing method not found");
940 939 }
941 940 }
942 941
943 942 private native Object[] getEnclosingMethod0();
944 943
945 944 private EnclosingMethodInfo getEnclosingMethodInfo() {
946 945 Object[] enclosingInfo = getEnclosingMethod0();
947 946 if (enclosingInfo == null)
948 947 return null;
949 948 else {
950 949 return new EnclosingMethodInfo(enclosingInfo);
951 950 }
952 951 }
953 952
954 953 private final static class EnclosingMethodInfo {
955 954 private Class<?> enclosingClass;
956 955 private String name;
957 956 private String descriptor;
958 957
959 958 private EnclosingMethodInfo(Object[] enclosingInfo) {
960 959 if (enclosingInfo.length != 3)
961 960 throw new InternalError("Malformed enclosing method information");
962 961 try {
963 962 // The array is expected to have three elements:
964 963
965 964 // the immediately enclosing class
966 965 enclosingClass = (Class<?>) enclosingInfo[0];
967 966 assert(enclosingClass != null);
968 967
969 968 // the immediately enclosing method or constructor's
970 969 // name (can be null).
971 970 name = (String) enclosingInfo[1];
972 971
973 972 // the immediately enclosing method or constructor's
974 973 // descriptor (null iff name is).
975 974 descriptor = (String) enclosingInfo[2];
976 975 assert((name != null && descriptor != null) || name == descriptor);
977 976 } catch (ClassCastException cce) {
978 977 throw new InternalError("Invalid type in enclosing method information", cce);
979 978 }
980 979 }
981 980
982 981 boolean isPartial() {
983 982 return enclosingClass == null || name == null || descriptor == null;
984 983 }
985 984
986 985 boolean isConstructor() { return !isPartial() && "<init>".equals(name); }
987 986
988 987 boolean isMethod() { return !isPartial() && !isConstructor() && !"<clinit>".equals(name); }
989 988
990 989 Class<?> getEnclosingClass() { return enclosingClass; }
991 990
992 991 String getName() { return name; }
993 992
994 993 String getDescriptor() { return descriptor; }
995 994
996 995 }
997 996
998 997 private static Class<?> toClass(Type o) {
999 998 if (o instanceof GenericArrayType)
1000 999 return Array.newInstance(toClass(((GenericArrayType)o).getGenericComponentType()),
1001 1000 0)
1002 1001 .getClass();
1003 1002 return (Class<?>)o;
1004 1003 }
1005 1004
1006 1005 /**
1007 1006 * If this {@code Class} object represents a local or anonymous
1008 1007 * class within a constructor, returns a {@link
1009 1008 * java.lang.reflect.Constructor Constructor} object representing
1010 1009 * the immediately enclosing constructor of the underlying
1011 1010 * class. Returns {@code null} otherwise. In particular, this
1012 1011 * method returns {@code null} if the underlying class is a local
1013 1012 * or anonymous class immediately enclosed by a type declaration,
1014 1013 * instance initializer or static initializer.
1015 1014 *
1016 1015 * @return the immediately enclosing constructor of the underlying class, if
1017 1016 * that class is a local or anonymous class; otherwise {@code null}.
1018 1017 * @since 1.5
1019 1018 */
1020 1019 public Constructor<?> getEnclosingConstructor() {
1021 1020 EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
1022 1021
1023 1022 if (enclosingInfo == null)
1024 1023 return null;
1025 1024 else {
1026 1025 if (!enclosingInfo.isConstructor())
1027 1026 return null;
1028 1027
1029 1028 ConstructorRepository typeInfo = ConstructorRepository.make(enclosingInfo.getDescriptor(),
1030 1029 getFactory());
1031 1030 Type [] parameterTypes = typeInfo.getParameterTypes();
1032 1031 Class<?>[] parameterClasses = new Class<?>[parameterTypes.length];
1033 1032
1034 1033 // Convert Types to Classes; returned types *should*
1035 1034 // be class objects since the methodDescriptor's used
1036 1035 // don't have generics information
1037 1036 for(int i = 0; i < parameterClasses.length; i++)
1038 1037 parameterClasses[i] = toClass(parameterTypes[i]);
1039 1038
1040 1039 /*
1041 1040 * Loop over all declared constructors; match number
1042 1041 * of and type of parameters.
1043 1042 */
1044 1043 for(Constructor<?> c: enclosingInfo.getEnclosingClass().getDeclaredConstructors()) {
1045 1044 Class<?>[] candidateParamClasses = c.getParameterTypes();
1046 1045 if (candidateParamClasses.length == parameterClasses.length) {
1047 1046 boolean matches = true;
1048 1047 for(int i = 0; i < candidateParamClasses.length; i++) {
1049 1048 if (!candidateParamClasses[i].equals(parameterClasses[i])) {
1050 1049 matches = false;
1051 1050 break;
1052 1051 }
1053 1052 }
1054 1053
1055 1054 if (matches)
1056 1055 return c;
1057 1056 }
1058 1057 }
1059 1058
1060 1059 throw new InternalError("Enclosing constructor not found");
1061 1060 }
1062 1061 }
1063 1062
1064 1063
1065 1064 /**
1066 1065 * If the class or interface represented by this {@code Class} object
1067 1066 * is a member of another class, returns the {@code Class} object
1068 1067 * representing the class in which it was declared. This method returns
1069 1068 * null if this class or interface is not a member of any other class. If
1070 1069 * this {@code Class} object represents an array class, a primitive
1071 1070 * type, or void,then this method returns null.
1072 1071 *
1073 1072 * @return the declaring class for this class
1074 1073 * @since JDK1.1
1075 1074 */
1076 1075 public native Class<?> getDeclaringClass();
1077 1076
1078 1077
1079 1078 /**
1080 1079 * Returns the immediately enclosing class of the underlying
1081 1080 * class. If the underlying class is a top level class this
1082 1081 * method returns {@code null}.
1083 1082 * @return the immediately enclosing class of the underlying class
1084 1083 * @since 1.5
1085 1084 */
1086 1085 public Class<?> getEnclosingClass() {
1087 1086 // There are five kinds of classes (or interfaces):
1088 1087 // a) Top level classes
1089 1088 // b) Nested classes (static member classes)
1090 1089 // c) Inner classes (non-static member classes)
1091 1090 // d) Local classes (named classes declared within a method)
1092 1091 // e) Anonymous classes
1093 1092
1094 1093
1095 1094 // JVM Spec 4.8.6: A class must have an EnclosingMethod
1096 1095 // attribute if and only if it is a local class or an
1097 1096 // anonymous class.
1098 1097 EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
1099 1098
1100 1099 if (enclosingInfo == null) {
1101 1100 // This is a top level or a nested class or an inner class (a, b, or c)
1102 1101 return getDeclaringClass();
1103 1102 } else {
1104 1103 Class<?> enclosingClass = enclosingInfo.getEnclosingClass();
1105 1104 // This is a local class or an anonymous class (d or e)
1106 1105 if (enclosingClass == this || enclosingClass == null)
1107 1106 throw new InternalError("Malformed enclosing method information");
1108 1107 else
1109 1108 return enclosingClass;
1110 1109 }
1111 1110 }
1112 1111
1113 1112 /**
1114 1113 * Returns the simple name of the underlying class as given in the
1115 1114 * source code. Returns an empty string if the underlying class is
1116 1115 * anonymous.
1117 1116 *
1118 1117 * <p>The simple name of an array is the simple name of the
1119 1118 * component type with "[]" appended. In particular the simple
1120 1119 * name of an array whose component type is anonymous is "[]".
1121 1120 *
1122 1121 * @return the simple name of the underlying class
1123 1122 * @since 1.5
1124 1123 */
1125 1124 public String getSimpleName() {
1126 1125 if (isArray())
1127 1126 return getComponentType().getSimpleName()+"[]";
1128 1127
1129 1128 String simpleName = getSimpleBinaryName();
1130 1129 if (simpleName == null) { // top level class
1131 1130 simpleName = getName();
1132 1131 return simpleName.substring(simpleName.lastIndexOf(".")+1); // strip the package name
1133 1132 }
1134 1133 // According to JLS3 "Binary Compatibility" (13.1) the binary
1135 1134 // name of non-package classes (not top level) is the binary
1136 1135 // name of the immediately enclosing class followed by a '$' followed by:
1137 1136 // (for nested and inner classes): the simple name.
1138 1137 // (for local classes): 1 or more digits followed by the simple name.
1139 1138 // (for anonymous classes): 1 or more digits.
1140 1139
1141 1140 // Since getSimpleBinaryName() will strip the binary name of
1142 1141 // the immediatly enclosing class, we are now looking at a
1143 1142 // string that matches the regular expression "\$[0-9]*"
1144 1143 // followed by a simple name (considering the simple of an
1145 1144 // anonymous class to be the empty string).
1146 1145
1147 1146 // Remove leading "\$[0-9]*" from the name
1148 1147 int length = simpleName.length();
1149 1148 if (length < 1 || simpleName.charAt(0) != '$')
1150 1149 throw new InternalError("Malformed class name");
1151 1150 int index = 1;
1152 1151 while (index < length && isAsciiDigit(simpleName.charAt(index)))
1153 1152 index++;
1154 1153 // Eventually, this is the empty string iff this is an anonymous class
1155 1154 return simpleName.substring(index);
1156 1155 }
1157 1156
1158 1157 /**
1159 1158 * Character.isDigit answers {@code true} to some non-ascii
1160 1159 * digits. This one does not.
1161 1160 */
1162 1161 private static boolean isAsciiDigit(char c) {
1163 1162 return '0' <= c && c <= '9';
1164 1163 }
1165 1164
1166 1165 /**
1167 1166 * Returns the canonical name of the underlying class as
1168 1167 * defined by the Java Language Specification. Returns null if
1169 1168 * the underlying class does not have a canonical name (i.e., if
1170 1169 * it is a local or anonymous class or an array whose component
1171 1170 * type does not have a canonical name).
1172 1171 * @return the canonical name of the underlying class if it exists, and
1173 1172 * {@code null} otherwise.
1174 1173 * @since 1.5
1175 1174 */
1176 1175 public String getCanonicalName() {
1177 1176 if (isArray()) {
1178 1177 String canonicalName = getComponentType().getCanonicalName();
1179 1178 if (canonicalName != null)
1180 1179 return canonicalName + "[]";
1181 1180 else
1182 1181 return null;
1183 1182 }
1184 1183 if (isLocalOrAnonymousClass())
1185 1184 return null;
1186 1185 Class<?> enclosingClass = getEnclosingClass();
1187 1186 if (enclosingClass == null) { // top level class
1188 1187 return getName();
1189 1188 } else {
1190 1189 String enclosingName = enclosingClass.getCanonicalName();
1191 1190 if (enclosingName == null)
1192 1191 return null;
1193 1192 return enclosingName + "." + getSimpleName();
1194 1193 }
1195 1194 }
1196 1195
1197 1196 /**
1198 1197 * Returns {@code true} if and only if the underlying class
1199 1198 * is an anonymous class.
1200 1199 *
1201 1200 * @return {@code true} if and only if this class is an anonymous class.
1202 1201 * @since 1.5
1203 1202 */
1204 1203 public boolean isAnonymousClass() {
1205 1204 return "".equals(getSimpleName());
1206 1205 }
1207 1206
1208 1207 /**
1209 1208 * Returns {@code true} if and only if the underlying class
1210 1209 * is a local class.
1211 1210 *
1212 1211 * @return {@code true} if and only if this class is a local class.
1213 1212 * @since 1.5
1214 1213 */
1215 1214 public boolean isLocalClass() {
1216 1215 return isLocalOrAnonymousClass() && !isAnonymousClass();
1217 1216 }
1218 1217
1219 1218 /**
1220 1219 * Returns {@code true} if and only if the underlying class
1221 1220 * is a member class.
1222 1221 *
1223 1222 * @return {@code true} if and only if this class is a member class.
1224 1223 * @since 1.5
1225 1224 */
1226 1225 public boolean isMemberClass() {
1227 1226 return getSimpleBinaryName() != null && !isLocalOrAnonymousClass();
1228 1227 }
1229 1228
1230 1229 /**
1231 1230 * Returns the "simple binary name" of the underlying class, i.e.,
1232 1231 * the binary name without the leading enclosing class name.
1233 1232 * Returns {@code null} if the underlying class is a top level
1234 1233 * class.
1235 1234 */
1236 1235 private String getSimpleBinaryName() {
1237 1236 Class<?> enclosingClass = getEnclosingClass();
1238 1237 if (enclosingClass == null) // top level class
1239 1238 return null;
1240 1239 // Otherwise, strip the enclosing class' name
1241 1240 try {
1242 1241 return getName().substring(enclosingClass.getName().length());
1243 1242 } catch (IndexOutOfBoundsException ex) {
1244 1243 throw new InternalError("Malformed class name", ex);
1245 1244 }
1246 1245 }
1247 1246
1248 1247 /**
1249 1248 * Returns {@code true} if this is a local class or an anonymous
1250 1249 * class. Returns {@code false} otherwise.
1251 1250 */
1252 1251 private boolean isLocalOrAnonymousClass() {
1253 1252 // JVM Spec 4.8.6: A class must have an EnclosingMethod
1254 1253 // attribute if and only if it is a local class or an
1255 1254 // anonymous class.
1256 1255 return getEnclosingMethodInfo() != null;
1257 1256 }
1258 1257
1259 1258 /**
1260 1259 * Returns an array containing {@code Class} objects representing all
1261 1260 * the public classes and interfaces that are members of the class
1262 1261 * represented by this {@code Class} object. This includes public
1263 1262 * class and interface members inherited from superclasses and public class
1264 1263 * and interface members declared by the class. This method returns an
1265 1264 * array of length 0 if this {@code Class} object has no public member
1266 1265 * classes or interfaces. This method also returns an array of length 0 if
1267 1266 * this {@code Class} object represents a primitive type, an array
1268 1267 * class, or void.
1269 1268 *
1270 1269 * @return the array of {@code Class} objects representing the public
1271 1270 * members of this class
1272 1271 * @exception SecurityException
1273 1272 * If a security manager, <i>s</i>, is present and any of the
1274 1273 * following conditions is met:
1275 1274 *
1276 1275 * <ul>
1277 1276 *
1278 1277 * <li> invocation of
1279 1278 * {@link SecurityManager#checkMemberAccess
1280 1279 * s.checkMemberAccess(this, Member.PUBLIC)} method
1281 1280 * denies access to the classes within this class
1282 1281 *
1283 1282 * <li> the caller's class loader is not the same as or an
1284 1283 * ancestor of the class loader for the current class and
1285 1284 * invocation of {@link SecurityManager#checkPackageAccess
1286 1285 * s.checkPackageAccess()} denies access to the package
1287 1286 * of this class
1288 1287 *
1289 1288 * </ul>
1290 1289 *
1291 1290 * @since JDK1.1
1292 1291 */
1293 1292 public Class<?>[] getClasses() {
1294 1293 // be very careful not to change the stack depth of this
1295 1294 // checkMemberAccess call for security reasons
1296 1295 // see java.lang.SecurityManager.checkMemberAccess
1297 1296 checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
1298 1297
1299 1298 // Privileged so this implementation can look at DECLARED classes,
1300 1299 // something the caller might not have privilege to do. The code here
1301 1300 // is allowed to look at DECLARED classes because (1) it does not hand
1302 1301 // out anything other than public members and (2) public member access
1303 1302 // has already been ok'd by the SecurityManager.
1304 1303
1305 1304 return java.security.AccessController.doPrivileged(
1306 1305 new java.security.PrivilegedAction<Class<?>[]>() {
1307 1306 public Class<?>[] run() {
1308 1307 List<Class<?>> list = new ArrayList<>();
1309 1308 Class<?> currentClass = Class.this;
1310 1309 while (currentClass != null) {
1311 1310 Class<?>[] members = currentClass.getDeclaredClasses();
1312 1311 for (int i = 0; i < members.length; i++) {
1313 1312 if (Modifier.isPublic(members[i].getModifiers())) {
1314 1313 list.add(members[i]);
1315 1314 }
1316 1315 }
1317 1316 currentClass = currentClass.getSuperclass();
1318 1317 }
1319 1318 return list.toArray(new Class<?>[0]);
1320 1319 }
1321 1320 });
1322 1321 }
1323 1322
1324 1323
1325 1324 /**
1326 1325 * Returns an array containing {@code Field} objects reflecting all
1327 1326 * the accessible public fields of the class or interface represented by
1328 1327 * this {@code Class} object. The elements in the array returned are
1329 1328 * not sorted and are not in any particular order. This method returns an
1330 1329 * array of length 0 if the class or interface has no accessible public
1331 1330 * fields, or if it represents an array class, a primitive type, or void.
1332 1331 *
1333 1332 * <p> Specifically, if this {@code Class} object represents a class,
1334 1333 * this method returns the public fields of this class and of all its
1335 1334 * superclasses. If this {@code Class} object represents an
1336 1335 * interface, this method returns the fields of this interface and of all
1337 1336 * its superinterfaces.
1338 1337 *
1339 1338 * <p> The implicit length field for array class is not reflected by this
1340 1339 * method. User code should use the methods of class {@code Array} to
1341 1340 * manipulate arrays.
1342 1341 *
1343 1342 * <p> See <em>The Java Language Specification</em>, sections 8.2 and 8.3.
1344 1343 *
1345 1344 * @return the array of {@code Field} objects representing the
1346 1345 * public fields
1347 1346 * @exception SecurityException
1348 1347 * If a security manager, <i>s</i>, is present and any of the
1349 1348 * following conditions is met:
1350 1349 *
1351 1350 * <ul>
1352 1351 *
1353 1352 * <li> invocation of
1354 1353 * {@link SecurityManager#checkMemberAccess
1355 1354 * s.checkMemberAccess(this, Member.PUBLIC)} denies
1356 1355 * access to the fields within this class
1357 1356 *
1358 1357 * <li> the caller's class loader is not the same as or an
1359 1358 * ancestor of the class loader for the current class and
1360 1359 * invocation of {@link SecurityManager#checkPackageAccess
1361 1360 * s.checkPackageAccess()} denies access to the package
1362 1361 * of this class
1363 1362 *
1364 1363 * </ul>
1365 1364 *
1366 1365 * @since JDK1.1
1367 1366 */
1368 1367 public Field[] getFields() throws SecurityException {
1369 1368 // be very careful not to change the stack depth of this
1370 1369 // checkMemberAccess call for security reasons
1371 1370 // see java.lang.SecurityManager.checkMemberAccess
1372 1371 checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
1373 1372 return copyFields(privateGetPublicFields(null));
1374 1373 }
1375 1374
1376 1375
1377 1376 /**
1378 1377 * Returns an array containing {@code Method} objects reflecting all
1379 1378 * the public <em>member</em> methods of the class or interface represented
1380 1379 * by this {@code Class} object, including those declared by the class
1381 1380 * or interface and those inherited from superclasses and
1382 1381 * superinterfaces. Array classes return all the (public) member methods
1383 1382 * inherited from the {@code Object} class. The elements in the array
1384 1383 * returned are not sorted and are not in any particular order. This
1385 1384 * method returns an array of length 0 if this {@code Class} object
1386 1385 * represents a class or interface that has no public member methods, or if
1387 1386 * this {@code Class} object represents a primitive type or void.
1388 1387 *
1389 1388 * <p> The class initialization method {@code <clinit>} is not
1390 1389 * included in the returned array. If the class declares multiple public
1391 1390 * member methods with the same parameter types, they are all included in
1392 1391 * the returned array.
1393 1392 *
1394 1393 * <p> See <em>The Java Language Specification</em>, sections 8.2 and 8.4.
1395 1394 *
1396 1395 * @return the array of {@code Method} objects representing the
1397 1396 * public methods of this class
1398 1397 * @exception SecurityException
1399 1398 * If a security manager, <i>s</i>, is present and any of the
1400 1399 * following conditions is met:
1401 1400 *
1402 1401 * <ul>
1403 1402 *
1404 1403 * <li> invocation of
1405 1404 * {@link SecurityManager#checkMemberAccess
1406 1405 * s.checkMemberAccess(this, Member.PUBLIC)} denies
1407 1406 * access to the methods within this class
1408 1407 *
1409 1408 * <li> the caller's class loader is not the same as or an
1410 1409 * ancestor of the class loader for the current class and
1411 1410 * invocation of {@link SecurityManager#checkPackageAccess
1412 1411 * s.checkPackageAccess()} denies access to the package
1413 1412 * of this class
1414 1413 *
1415 1414 * </ul>
1416 1415 *
1417 1416 * @since JDK1.1
1418 1417 */
1419 1418 public Method[] getMethods() throws SecurityException {
1420 1419 // be very careful not to change the stack depth of this
1421 1420 // checkMemberAccess call for security reasons
1422 1421 // see java.lang.SecurityManager.checkMemberAccess
1423 1422 checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
1424 1423 return copyMethods(privateGetPublicMethods());
1425 1424 }
1426 1425
1427 1426
1428 1427 /**
1429 1428 * Returns an array containing {@code Constructor} objects reflecting
1430 1429 * all the public constructors of the class represented by this
1431 1430 * {@code Class} object. An array of length 0 is returned if the
1432 1431 * class has no public constructors, or if the class is an array class, or
1433 1432 * if the class reflects a primitive type or void.
1434 1433 *
1435 1434 * Note that while this method returns an array of {@code
1436 1435 * Constructor<T>} objects (that is an array of constructors from
1437 1436 * this class), the return type of this method is {@code
1438 1437 * Constructor<?>[]} and <em>not</em> {@code Constructor<T>[]} as
1439 1438 * might be expected. This less informative return type is
1440 1439 * necessary since after being returned from this method, the
1441 1440 * array could be modified to hold {@code Constructor} objects for
1442 1441 * different classes, which would violate the type guarantees of
1443 1442 * {@code Constructor<T>[]}.
1444 1443 *
1445 1444 * @return the array of {@code Constructor} objects representing the
1446 1445 * public constructors of this class
1447 1446 * @exception SecurityException
1448 1447 * If a security manager, <i>s</i>, is present and any of the
1449 1448 * following conditions is met:
1450 1449 *
1451 1450 * <ul>
1452 1451 *
1453 1452 * <li> invocation of
1454 1453 * {@link SecurityManager#checkMemberAccess
1455 1454 * s.checkMemberAccess(this, Member.PUBLIC)} denies
1456 1455 * access to the constructors within this class
1457 1456 *
1458 1457 * <li> the caller's class loader is not the same as or an
1459 1458 * ancestor of the class loader for the current class and
1460 1459 * invocation of {@link SecurityManager#checkPackageAccess
1461 1460 * s.checkPackageAccess()} denies access to the package
1462 1461 * of this class
1463 1462 *
1464 1463 * </ul>
1465 1464 *
1466 1465 * @since JDK1.1
1467 1466 */
1468 1467 public Constructor<?>[] getConstructors() throws SecurityException {
1469 1468 // be very careful not to change the stack depth of this
1470 1469 // checkMemberAccess call for security reasons
1471 1470 // see java.lang.SecurityManager.checkMemberAccess
1472 1471 checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
1473 1472 return copyConstructors(privateGetDeclaredConstructors(true));
1474 1473 }
1475 1474
1476 1475
1477 1476 /**
1478 1477 * Returns a {@code Field} object that reflects the specified public
1479 1478 * member field of the class or interface represented by this
1480 1479 * {@code Class} object. The {@code name} parameter is a
1481 1480 * {@code String} specifying the simple name of the desired field.
1482 1481 *
1483 1482 * <p> The field to be reflected is determined by the algorithm that
1484 1483 * follows. Let C be the class represented by this object:
1485 1484 * <OL>
1486 1485 * <LI> If C declares a public field with the name specified, that is the
1487 1486 * field to be reflected.</LI>
1488 1487 * <LI> If no field was found in step 1 above, this algorithm is applied
1489 1488 * recursively to each direct superinterface of C. The direct
1490 1489 * superinterfaces are searched in the order they were declared.</LI>
1491 1490 * <LI> If no field was found in steps 1 and 2 above, and C has a
1492 1491 * superclass S, then this algorithm is invoked recursively upon S.
1493 1492 * If C has no superclass, then a {@code NoSuchFieldException}
1494 1493 * is thrown.</LI>
1495 1494 * </OL>
1496 1495 *
1497 1496 * <p> See <em>The Java Language Specification</em>, sections 8.2 and 8.3.
1498 1497 *
1499 1498 * @param name the field name
1500 1499 * @return the {@code Field} object of this class specified by
1501 1500 * {@code name}
1502 1501 * @exception NoSuchFieldException if a field with the specified name is
1503 1502 * not found.
1504 1503 * @exception NullPointerException if {@code name} is {@code null}
1505 1504 * @exception SecurityException
1506 1505 * If a security manager, <i>s</i>, is present and any of the
1507 1506 * following conditions is met:
1508 1507 *
1509 1508 * <ul>
1510 1509 *
1511 1510 * <li> invocation of
1512 1511 * {@link SecurityManager#checkMemberAccess
1513 1512 * s.checkMemberAccess(this, Member.PUBLIC)} denies
1514 1513 * access to the field
1515 1514 *
1516 1515 * <li> the caller's class loader is not the same as or an
1517 1516 * ancestor of the class loader for the current class and
1518 1517 * invocation of {@link SecurityManager#checkPackageAccess
1519 1518 * s.checkPackageAccess()} denies access to the package
1520 1519 * of this class
1521 1520 *
1522 1521 * </ul>
1523 1522 *
1524 1523 * @since JDK1.1
1525 1524 */
1526 1525 public Field getField(String name)
1527 1526 throws NoSuchFieldException, SecurityException {
1528 1527 // be very careful not to change the stack depth of this
1529 1528 // checkMemberAccess call for security reasons
1530 1529 // see java.lang.SecurityManager.checkMemberAccess
1531 1530 checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
1532 1531 Field field = getField0(name);
1533 1532 if (field == null) {
1534 1533 throw new NoSuchFieldException(name);
1535 1534 }
1536 1535 return field;
1537 1536 }
1538 1537
1539 1538
1540 1539 /**
1541 1540 * Returns a {@code Method} object that reflects the specified public
1542 1541 * member method of the class or interface represented by this
1543 1542 * {@code Class} object. The {@code name} parameter is a
1544 1543 * {@code String} specifying the simple name of the desired method. The
1545 1544 * {@code parameterTypes} parameter is an array of {@code Class}
1546 1545 * objects that identify the method's formal parameter types, in declared
1547 1546 * order. If {@code parameterTypes} is {@code null}, it is
1548 1547 * treated as if it were an empty array.
1549 1548 *
1550 1549 * <p> If the {@code name} is "{@code <init>};"or "{@code <clinit>}" a
1551 1550 * {@code NoSuchMethodException} is raised. Otherwise, the method to
1552 1551 * be reflected is determined by the algorithm that follows. Let C be the
1553 1552 * class represented by this object:
1554 1553 * <OL>
1555 1554 * <LI> C is searched for any <I>matching methods</I>. If no matching
1556 1555 * method is found, the algorithm of step 1 is invoked recursively on
1557 1556 * the superclass of C.</LI>
1558 1557 * <LI> If no method was found in step 1 above, the superinterfaces of C
1559 1558 * are searched for a matching method. If any such method is found, it
1560 1559 * is reflected.</LI>
1561 1560 * </OL>
1562 1561 *
1563 1562 * To find a matching method in a class C: If C declares exactly one
1564 1563 * public method with the specified name and exactly the same formal
1565 1564 * parameter types, that is the method reflected. If more than one such
1566 1565 * method is found in C, and one of these methods has a return type that is
1567 1566 * more specific than any of the others, that method is reflected;
1568 1567 * otherwise one of the methods is chosen arbitrarily.
1569 1568 *
1570 1569 * <p>Note that there may be more than one matching method in a
1571 1570 * class because while the Java language forbids a class to
1572 1571 * declare multiple methods with the same signature but different
1573 1572 * return types, the Java virtual machine does not. This
1574 1573 * increased flexibility in the virtual machine can be used to
1575 1574 * implement various language features. For example, covariant
1576 1575 * returns can be implemented with {@linkplain
1577 1576 * java.lang.reflect.Method#isBridge bridge methods}; the bridge
1578 1577 * method and the method being overridden would have the same
1579 1578 * signature but different return types.
1580 1579 *
1581 1580 * <p> See <em>The Java Language Specification</em>, sections 8.2 and 8.4.
1582 1581 *
1583 1582 * @param name the name of the method
1584 1583 * @param parameterTypes the list of parameters
1585 1584 * @return the {@code Method} object that matches the specified
1586 1585 * {@code name} and {@code parameterTypes}
1587 1586 * @exception NoSuchMethodException if a matching method is not found
1588 1587 * or if the name is "<init>"or "<clinit>".
1589 1588 * @exception NullPointerException if {@code name} is {@code null}
1590 1589 * @exception SecurityException
1591 1590 * If a security manager, <i>s</i>, is present and any of the
1592 1591 * following conditions is met:
1593 1592 *
1594 1593 * <ul>
1595 1594 *
1596 1595 * <li> invocation of
1597 1596 * {@link SecurityManager#checkMemberAccess
1598 1597 * s.checkMemberAccess(this, Member.PUBLIC)} denies
1599 1598 * access to the method
1600 1599 *
1601 1600 * <li> the caller's class loader is not the same as or an
1602 1601 * ancestor of the class loader for the current class and
1603 1602 * invocation of {@link SecurityManager#checkPackageAccess
1604 1603 * s.checkPackageAccess()} denies access to the package
1605 1604 * of this class
1606 1605 *
1607 1606 * </ul>
1608 1607 *
1609 1608 * @since JDK1.1
1610 1609 */
1611 1610 public Method getMethod(String name, Class<?>... parameterTypes)
1612 1611 throws NoSuchMethodException, SecurityException {
1613 1612 // be very careful not to change the stack depth of this
1614 1613 // checkMemberAccess call for security reasons
1615 1614 // see java.lang.SecurityManager.checkMemberAccess
1616 1615 checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
1617 1616 Method method = getMethod0(name, parameterTypes);
1618 1617 if (method == null) {
1619 1618 throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
1620 1619 }
1621 1620 return method;
1622 1621 }
1623 1622
1624 1623
1625 1624 /**
1626 1625 * Returns a {@code Constructor} object that reflects the specified
1627 1626 * public constructor of the class represented by this {@code Class}
1628 1627 * object. The {@code parameterTypes} parameter is an array of
1629 1628 * {@code Class} objects that identify the constructor's formal
1630 1629 * parameter types, in declared order.
1631 1630 *
1632 1631 * If this {@code Class} object represents an inner class
1633 1632 * declared in a non-static context, the formal parameter types
1634 1633 * include the explicit enclosing instance as the first parameter.
1635 1634 *
1636 1635 * <p> The constructor to reflect is the public constructor of the class
1637 1636 * represented by this {@code Class} object whose formal parameter
1638 1637 * types match those specified by {@code parameterTypes}.
1639 1638 *
1640 1639 * @param parameterTypes the parameter array
1641 1640 * @return the {@code Constructor} object of the public constructor that
1642 1641 * matches the specified {@code parameterTypes}
1643 1642 * @exception NoSuchMethodException if a matching method is not found.
1644 1643 * @exception SecurityException
1645 1644 * If a security manager, <i>s</i>, is present and any of the
1646 1645 * following conditions is met:
1647 1646 *
1648 1647 * <ul>
1649 1648 *
1650 1649 * <li> invocation of
1651 1650 * {@link SecurityManager#checkMemberAccess
1652 1651 * s.checkMemberAccess(this, Member.PUBLIC)} denies
1653 1652 * access to the constructor
1654 1653 *
1655 1654 * <li> the caller's class loader is not the same as or an
1656 1655 * ancestor of the class loader for the current class and
1657 1656 * invocation of {@link SecurityManager#checkPackageAccess
1658 1657 * s.checkPackageAccess()} denies access to the package
1659 1658 * of this class
1660 1659 *
1661 1660 * </ul>
1662 1661 *
1663 1662 * @since JDK1.1
1664 1663 */
1665 1664 public Constructor<T> getConstructor(Class<?>... parameterTypes)
1666 1665 throws NoSuchMethodException, SecurityException {
1667 1666 // be very careful not to change the stack depth of this
1668 1667 // checkMemberAccess call for security reasons
1669 1668 // see java.lang.SecurityManager.checkMemberAccess
1670 1669 checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
1671 1670 return getConstructor0(parameterTypes, Member.PUBLIC);
1672 1671 }
1673 1672
1674 1673
1675 1674 /**
1676 1675 * Returns an array of {@code Class} objects reflecting all the
1677 1676 * classes and interfaces declared as members of the class represented by
1678 1677 * this {@code Class} object. This includes public, protected, default
1679 1678 * (package) access, and private classes and interfaces declared by the
1680 1679 * class, but excludes inherited classes and interfaces. This method
1681 1680 * returns an array of length 0 if the class declares no classes or
1682 1681 * interfaces as members, or if this {@code Class} object represents a
1683 1682 * primitive type, an array class, or void.
1684 1683 *
1685 1684 * @return the array of {@code Class} objects representing all the
1686 1685 * declared members of this class
1687 1686 * @exception SecurityException
1688 1687 * If a security manager, <i>s</i>, is present and any of the
1689 1688 * following conditions is met:
1690 1689 *
1691 1690 * <ul>
1692 1691 *
1693 1692 * <li> invocation of
1694 1693 * {@link SecurityManager#checkMemberAccess
1695 1694 * s.checkMemberAccess(this, Member.DECLARED)} denies
1696 1695 * access to the declared classes within this class
1697 1696 *
1698 1697 * <li> the caller's class loader is not the same as or an
1699 1698 * ancestor of the class loader for the current class and
1700 1699 * invocation of {@link SecurityManager#checkPackageAccess
1701 1700 * s.checkPackageAccess()} denies access to the package
1702 1701 * of this class
1703 1702 *
1704 1703 * </ul>
1705 1704 *
1706 1705 * @since JDK1.1
1707 1706 */
1708 1707 public Class<?>[] getDeclaredClasses() throws SecurityException {
1709 1708 // be very careful not to change the stack depth of this
1710 1709 // checkMemberAccess call for security reasons
1711 1710 // see java.lang.SecurityManager.checkMemberAccess
1712 1711 checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
1713 1712 return getDeclaredClasses0();
1714 1713 }
1715 1714
1716 1715
1717 1716 /**
1718 1717 * Returns an array of {@code Field} objects reflecting all the fields
1719 1718 * declared by the class or interface represented by this
1720 1719 * {@code Class} object. This includes public, protected, default
1721 1720 * (package) access, and private fields, but excludes inherited fields.
1722 1721 * The elements in the array returned are not sorted and are not in any
1723 1722 * particular order. This method returns an array of length 0 if the class
1724 1723 * or interface declares no fields, or if this {@code Class} object
1725 1724 * represents a primitive type, an array class, or void.
1726 1725 *
1727 1726 * <p> See <em>The Java Language Specification</em>, sections 8.2 and 8.3.
1728 1727 *
1729 1728 * @return the array of {@code Field} objects representing all the
1730 1729 * declared fields of this class
1731 1730 * @exception SecurityException
1732 1731 * If a security manager, <i>s</i>, is present and any of the
1733 1732 * following conditions is met:
1734 1733 *
1735 1734 * <ul>
1736 1735 *
1737 1736 * <li> invocation of
1738 1737 * {@link SecurityManager#checkMemberAccess
1739 1738 * s.checkMemberAccess(this, Member.DECLARED)} denies
1740 1739 * access to the declared fields within this class
1741 1740 *
1742 1741 * <li> the caller's class loader is not the same as or an
1743 1742 * ancestor of the class loader for the current class and
1744 1743 * invocation of {@link SecurityManager#checkPackageAccess
1745 1744 * s.checkPackageAccess()} denies access to the package
1746 1745 * of this class
1747 1746 *
1748 1747 * </ul>
1749 1748 *
1750 1749 * @since JDK1.1
1751 1750 */
1752 1751 public Field[] getDeclaredFields() throws SecurityException {
1753 1752 // be very careful not to change the stack depth of this
1754 1753 // checkMemberAccess call for security reasons
1755 1754 // see java.lang.SecurityManager.checkMemberAccess
1756 1755 checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
1757 1756 return copyFields(privateGetDeclaredFields(false));
1758 1757 }
1759 1758
1760 1759
1761 1760 /**
1762 1761 * Returns an array of {@code Method} objects reflecting all the
1763 1762 * methods declared by the class or interface represented by this
1764 1763 * {@code Class} object. This includes public, protected, default
1765 1764 * (package) access, and private methods, but excludes inherited methods.
1766 1765 * The elements in the array returned are not sorted and are not in any
1767 1766 * particular order. This method returns an array of length 0 if the class
1768 1767 * or interface declares no methods, or if this {@code Class} object
1769 1768 * represents a primitive type, an array class, or void. The class
1770 1769 * initialization method {@code <clinit>} is not included in the
1771 1770 * returned array. If the class declares multiple public member methods
1772 1771 * with the same parameter types, they are all included in the returned
1773 1772 * array.
1774 1773 *
1775 1774 * <p> See <em>The Java Language Specification</em>, section 8.2.
1776 1775 *
1777 1776 * @return the array of {@code Method} objects representing all the
1778 1777 * declared methods of this class
1779 1778 * @exception SecurityException
1780 1779 * If a security manager, <i>s</i>, is present and any of the
1781 1780 * following conditions is met:
1782 1781 *
1783 1782 * <ul>
1784 1783 *
1785 1784 * <li> invocation of
1786 1785 * {@link SecurityManager#checkMemberAccess
1787 1786 * s.checkMemberAccess(this, Member.DECLARED)} denies
1788 1787 * access to the declared methods within this class
1789 1788 *
1790 1789 * <li> the caller's class loader is not the same as or an
1791 1790 * ancestor of the class loader for the current class and
1792 1791 * invocation of {@link SecurityManager#checkPackageAccess
1793 1792 * s.checkPackageAccess()} denies access to the package
1794 1793 * of this class
1795 1794 *
1796 1795 * </ul>
1797 1796 *
1798 1797 * @since JDK1.1
1799 1798 */
1800 1799 public Method[] getDeclaredMethods() throws SecurityException {
1801 1800 // be very careful not to change the stack depth of this
1802 1801 // checkMemberAccess call for security reasons
1803 1802 // see java.lang.SecurityManager.checkMemberAccess
1804 1803 checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
1805 1804 return copyMethods(privateGetDeclaredMethods(false));
1806 1805 }
1807 1806
1808 1807
1809 1808 /**
1810 1809 * Returns an array of {@code Constructor} objects reflecting all the
1811 1810 * constructors declared by the class represented by this
1812 1811 * {@code Class} object. These are public, protected, default
1813 1812 * (package) access, and private constructors. The elements in the array
1814 1813 * returned are not sorted and are not in any particular order. If the
1815 1814 * class has a default constructor, it is included in the returned array.
1816 1815 * This method returns an array of length 0 if this {@code Class}
1817 1816 * object represents an interface, a primitive type, an array class, or
1818 1817 * void.
1819 1818 *
1820 1819 * <p> See <em>The Java Language Specification</em>, section 8.2.
1821 1820 *
1822 1821 * @return the array of {@code Constructor} objects representing all the
1823 1822 * declared constructors of this class
1824 1823 * @exception SecurityException
1825 1824 * If a security manager, <i>s</i>, is present and any of the
1826 1825 * following conditions is met:
1827 1826 *
1828 1827 * <ul>
1829 1828 *
1830 1829 * <li> invocation of
1831 1830 * {@link SecurityManager#checkMemberAccess
1832 1831 * s.checkMemberAccess(this, Member.DECLARED)} denies
1833 1832 * access to the declared constructors within this class
1834 1833 *
1835 1834 * <li> the caller's class loader is not the same as or an
1836 1835 * ancestor of the class loader for the current class and
1837 1836 * invocation of {@link SecurityManager#checkPackageAccess
1838 1837 * s.checkPackageAccess()} denies access to the package
1839 1838 * of this class
1840 1839 *
1841 1840 * </ul>
1842 1841 *
1843 1842 * @since JDK1.1
1844 1843 */
1845 1844 public Constructor<?>[] getDeclaredConstructors() throws SecurityException {
1846 1845 // be very careful not to change the stack depth of this
1847 1846 // checkMemberAccess call for security reasons
1848 1847 // see java.lang.SecurityManager.checkMemberAccess
1849 1848 checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
1850 1849 return copyConstructors(privateGetDeclaredConstructors(false));
1851 1850 }
1852 1851
1853 1852
1854 1853 /**
1855 1854 * Returns a {@code Field} object that reflects the specified declared
1856 1855 * field of the class or interface represented by this {@code Class}
1857 1856 * object. The {@code name} parameter is a {@code String} that
1858 1857 * specifies the simple name of the desired field. Note that this method
1859 1858 * will not reflect the {@code length} field of an array class.
1860 1859 *
1861 1860 * @param name the name of the field
1862 1861 * @return the {@code Field} object for the specified field in this
1863 1862 * class
1864 1863 * @exception NoSuchFieldException if a field with the specified name is
1865 1864 * not found.
1866 1865 * @exception NullPointerException if {@code name} is {@code null}
1867 1866 * @exception SecurityException
1868 1867 * If a security manager, <i>s</i>, is present and any of the
1869 1868 * following conditions is met:
1870 1869 *
1871 1870 * <ul>
1872 1871 *
1873 1872 * <li> invocation of
1874 1873 * {@link SecurityManager#checkMemberAccess
1875 1874 * s.checkMemberAccess(this, Member.DECLARED)} denies
1876 1875 * access to the declared field
1877 1876 *
1878 1877 * <li> the caller's class loader is not the same as or an
1879 1878 * ancestor of the class loader for the current class and
1880 1879 * invocation of {@link SecurityManager#checkPackageAccess
1881 1880 * s.checkPackageAccess()} denies access to the package
1882 1881 * of this class
1883 1882 *
1884 1883 * </ul>
1885 1884 *
1886 1885 * @since JDK1.1
1887 1886 */
1888 1887 public Field getDeclaredField(String name)
1889 1888 throws NoSuchFieldException, SecurityException {
1890 1889 // be very careful not to change the stack depth of this
1891 1890 // checkMemberAccess call for security reasons
1892 1891 // see java.lang.SecurityManager.checkMemberAccess
1893 1892 checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
1894 1893 Field field = searchFields(privateGetDeclaredFields(false), name);
1895 1894 if (field == null) {
1896 1895 throw new NoSuchFieldException(name);
1897 1896 }
1898 1897 return field;
1899 1898 }
1900 1899
1901 1900
1902 1901 /**
1903 1902 * Returns a {@code Method} object that reflects the specified
1904 1903 * declared method of the class or interface represented by this
1905 1904 * {@code Class} object. The {@code name} parameter is a
1906 1905 * {@code String} that specifies the simple name of the desired
1907 1906 * method, and the {@code parameterTypes} parameter is an array of
1908 1907 * {@code Class} objects that identify the method's formal parameter
1909 1908 * types, in declared order. If more than one method with the same
1910 1909 * parameter types is declared in a class, and one of these methods has a
1911 1910 * return type that is more specific than any of the others, that method is
1912 1911 * returned; otherwise one of the methods is chosen arbitrarily. If the
1913 1912 * name is "<init>"or "<clinit>" a {@code NoSuchMethodException}
1914 1913 * is raised.
1915 1914 *
1916 1915 * @param name the name of the method
1917 1916 * @param parameterTypes the parameter array
1918 1917 * @return the {@code Method} object for the method of this class
1919 1918 * matching the specified name and parameters
1920 1919 * @exception NoSuchMethodException if a matching method is not found.
1921 1920 * @exception NullPointerException if {@code name} is {@code null}
1922 1921 * @exception SecurityException
1923 1922 * If a security manager, <i>s</i>, is present and any of the
1924 1923 * following conditions is met:
1925 1924 *
1926 1925 * <ul>
1927 1926 *
1928 1927 * <li> invocation of
1929 1928 * {@link SecurityManager#checkMemberAccess
1930 1929 * s.checkMemberAccess(this, Member.DECLARED)} denies
1931 1930 * access to the declared method
1932 1931 *
1933 1932 * <li> the caller's class loader is not the same as or an
1934 1933 * ancestor of the class loader for the current class and
1935 1934 * invocation of {@link SecurityManager#checkPackageAccess
1936 1935 * s.checkPackageAccess()} denies access to the package
1937 1936 * of this class
1938 1937 *
1939 1938 * </ul>
1940 1939 *
1941 1940 * @since JDK1.1
1942 1941 */
1943 1942 public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
1944 1943 throws NoSuchMethodException, SecurityException {
1945 1944 // be very careful not to change the stack depth of this
1946 1945 // checkMemberAccess call for security reasons
1947 1946 // see java.lang.SecurityManager.checkMemberAccess
1948 1947 checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
1949 1948 Method method = searchMethods(privateGetDeclaredMethods(false), name, parameterTypes);
1950 1949 if (method == null) {
1951 1950 throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
1952 1951 }
1953 1952 return method;
1954 1953 }
1955 1954
1956 1955
1957 1956 /**
1958 1957 * Returns a {@code Constructor} object that reflects the specified
1959 1958 * constructor of the class or interface represented by this
1960 1959 * {@code Class} object. The {@code parameterTypes} parameter is
1961 1960 * an array of {@code Class} objects that identify the constructor's
1962 1961 * formal parameter types, in declared order.
1963 1962 *
1964 1963 * If this {@code Class} object represents an inner class
1965 1964 * declared in a non-static context, the formal parameter types
1966 1965 * include the explicit enclosing instance as the first parameter.
1967 1966 *
1968 1967 * @param parameterTypes the parameter array
1969 1968 * @return The {@code Constructor} object for the constructor with the
1970 1969 * specified parameter list
1971 1970 * @exception NoSuchMethodException if a matching method is not found.
1972 1971 * @exception SecurityException
1973 1972 * If a security manager, <i>s</i>, is present and any of the
1974 1973 * following conditions is met:
1975 1974 *
1976 1975 * <ul>
1977 1976 *
1978 1977 * <li> invocation of
1979 1978 * {@link SecurityManager#checkMemberAccess
1980 1979 * s.checkMemberAccess(this, Member.DECLARED)} denies
1981 1980 * access to the declared constructor
1982 1981 *
1983 1982 * <li> the caller's class loader is not the same as or an
1984 1983 * ancestor of the class loader for the current class and
1985 1984 * invocation of {@link SecurityManager#checkPackageAccess
1986 1985 * s.checkPackageAccess()} denies access to the package
1987 1986 * of this class
1988 1987 *
1989 1988 * </ul>
1990 1989 *
1991 1990 * @since JDK1.1
1992 1991 */
1993 1992 public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
1994 1993 throws NoSuchMethodException, SecurityException {
1995 1994 // be very careful not to change the stack depth of this
1996 1995 // checkMemberAccess call for security reasons
1997 1996 // see java.lang.SecurityManager.checkMemberAccess
1998 1997 checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
1999 1998 return getConstructor0(parameterTypes, Member.DECLARED);
2000 1999 }
2001 2000
2002 2001 /**
2003 2002 * Finds a resource with a given name. The rules for searching resources
2004 2003 * associated with a given class are implemented by the defining
2005 2004 * {@linkplain ClassLoader class loader} of the class. This method
2006 2005 * delegates to this object's class loader. If this object was loaded by
2007 2006 * the bootstrap class loader, the method delegates to {@link
2008 2007 * ClassLoader#getSystemResourceAsStream}.
2009 2008 *
2010 2009 * <p> Before delegation, an absolute resource name is constructed from the
2011 2010 * given resource name using this algorithm:
2012 2011 *
2013 2012 * <ul>
2014 2013 *
2015 2014 * <li> If the {@code name} begins with a {@code '/'}
2016 2015 * (<tt>'\u002f'</tt>), then the absolute name of the resource is the
2017 2016 * portion of the {@code name} following the {@code '/'}.
2018 2017 *
2019 2018 * <li> Otherwise, the absolute name is of the following form:
2020 2019 *
2021 2020 * <blockquote>
2022 2021 * {@code modified_package_name/name}
2023 2022 * </blockquote>
2024 2023 *
2025 2024 * <p> Where the {@code modified_package_name} is the package name of this
2026 2025 * object with {@code '/'} substituted for {@code '.'}
2027 2026 * (<tt>'\u002e'</tt>).
2028 2027 *
2029 2028 * </ul>
2030 2029 *
2031 2030 * @param name name of the desired resource
2032 2031 * @return A {@link java.io.InputStream} object or {@code null} if
2033 2032 * no resource with this name is found
2034 2033 * @throws NullPointerException If {@code name} is {@code null}
2035 2034 * @since JDK1.1
2036 2035 */
2037 2036 public InputStream getResourceAsStream(String name) {
2038 2037 name = resolveName(name);
2039 2038 ClassLoader cl = getClassLoader0();
2040 2039 if (cl==null) {
2041 2040 // A system class.
2042 2041 return ClassLoader.getSystemResourceAsStream(name);
2043 2042 }
2044 2043 return cl.getResourceAsStream(name);
2045 2044 }
2046 2045
2047 2046 /**
2048 2047 * Finds a resource with a given name. The rules for searching resources
2049 2048 * associated with a given class are implemented by the defining
2050 2049 * {@linkplain ClassLoader class loader} of the class. This method
2051 2050 * delegates to this object's class loader. If this object was loaded by
2052 2051 * the bootstrap class loader, the method delegates to {@link
2053 2052 * ClassLoader#getSystemResource}.
2054 2053 *
2055 2054 * <p> Before delegation, an absolute resource name is constructed from the
2056 2055 * given resource name using this algorithm:
2057 2056 *
2058 2057 * <ul>
2059 2058 *
2060 2059 * <li> If the {@code name} begins with a {@code '/'}
2061 2060 * (<tt>'\u002f'</tt>), then the absolute name of the resource is the
2062 2061 * portion of the {@code name} following the {@code '/'}.
2063 2062 *
2064 2063 * <li> Otherwise, the absolute name is of the following form:
2065 2064 *
2066 2065 * <blockquote>
2067 2066 * {@code modified_package_name/name}
2068 2067 * </blockquote>
2069 2068 *
2070 2069 * <p> Where the {@code modified_package_name} is the package name of this
2071 2070 * object with {@code '/'} substituted for {@code '.'}
2072 2071 * (<tt>'\u002e'</tt>).
2073 2072 *
2074 2073 * </ul>
2075 2074 *
2076 2075 * @param name name of the desired resource
2077 2076 * @return A {@link java.net.URL} object or {@code null} if no
2078 2077 * resource with this name is found
2079 2078 * @since JDK1.1
2080 2079 */
2081 2080 public java.net.URL getResource(String name) {
2082 2081 name = resolveName(name);
2083 2082 ClassLoader cl = getClassLoader0();
2084 2083 if (cl==null) {
2085 2084 // A system class.
2086 2085 return ClassLoader.getSystemResource(name);
2087 2086 }
2088 2087 return cl.getResource(name);
2089 2088 }
2090 2089
2091 2090
2092 2091
2093 2092 /** protection domain returned when the internal domain is null */
2094 2093 private static java.security.ProtectionDomain allPermDomain;
2095 2094
2096 2095
2097 2096 /**
2098 2097 * Returns the {@code ProtectionDomain} of this class. If there is a
2099 2098 * security manager installed, this method first calls the security
2100 2099 * manager's {@code checkPermission} method with a
2101 2100 * {@code RuntimePermission("getProtectionDomain")} permission to
2102 2101 * ensure it's ok to get the
2103 2102 * {@code ProtectionDomain}.
2104 2103 *
2105 2104 * @return the ProtectionDomain of this class
2106 2105 *
2107 2106 * @throws SecurityException
2108 2107 * if a security manager exists and its
2109 2108 * {@code checkPermission} method doesn't allow
2110 2109 * getting the ProtectionDomain.
2111 2110 *
2112 2111 * @see java.security.ProtectionDomain
2113 2112 * @see SecurityManager#checkPermission
2114 2113 * @see java.lang.RuntimePermission
2115 2114 * @since 1.2
2116 2115 */
2117 2116 public java.security.ProtectionDomain getProtectionDomain() {
2118 2117 SecurityManager sm = System.getSecurityManager();
2119 2118 if (sm != null) {
2120 2119 sm.checkPermission(SecurityConstants.GET_PD_PERMISSION);
2121 2120 }
2122 2121 java.security.ProtectionDomain pd = getProtectionDomain0();
2123 2122 if (pd == null) {
2124 2123 if (allPermDomain == null) {
2125 2124 java.security.Permissions perms =
2126 2125 new java.security.Permissions();
2127 2126 perms.add(SecurityConstants.ALL_PERMISSION);
2128 2127 allPermDomain =
2129 2128 new java.security.ProtectionDomain(null, perms);
2130 2129 }
2131 2130 pd = allPermDomain;
2132 2131 }
2133 2132 return pd;
2134 2133 }
2135 2134
2136 2135
2137 2136 /**
2138 2137 * Returns the ProtectionDomain of this class.
2139 2138 */
2140 2139 private native java.security.ProtectionDomain getProtectionDomain0();
2141 2140
2142 2141
2143 2142 /**
2144 2143 * Set the ProtectionDomain for this class. Called by
2145 2144 * ClassLoader.defineClass.
2146 2145 */
2147 2146 native void setProtectionDomain0(java.security.ProtectionDomain pd);
2148 2147
2149 2148
2150 2149 /*
2151 2150 * Return the Virtual Machine's Class object for the named
2152 2151 * primitive type.
2153 2152 */
2154 2153 static native Class<?> getPrimitiveClass(String name);
2155 2154
2156 2155
2157 2156 /*
2158 2157 * Check if client is allowed to access members. If access is denied,
2159 2158 * throw a SecurityException.
2160 2159 *
2161 2160 * Be very careful not to change the stack depth of this checkMemberAccess
2162 2161 * call for security reasons.
2163 2162 * See java.lang.SecurityManager.checkMemberAccess.
2164 2163 *
2165 2164 * <p> Default policy: allow all clients access with normal Java access
2166 2165 * control.
2167 2166 */
2168 2167 private void checkMemberAccess(int which, ClassLoader ccl) {
2169 2168 SecurityManager s = System.getSecurityManager();
2170 2169 if (s != null) {
2171 2170 s.checkMemberAccess(this, which);
2172 2171 ClassLoader cl = getClassLoader0();
2173 2172 if ((ccl != null) && (ccl != cl) &&
2174 2173 ((cl == null) || !cl.isAncestor(ccl))) {
2175 2174 String name = this.getName();
2176 2175 int i = name.lastIndexOf('.');
2177 2176 if (i != -1) {
2178 2177 s.checkPackageAccess(name.substring(0, i));
2179 2178 }
2180 2179 }
2181 2180 }
2182 2181 }
2183 2182
2184 2183 /**
2185 2184 * Add a package name prefix if the name is not absolute Remove leading "/"
2186 2185 * if name is absolute
2187 2186 */
2188 2187 private String resolveName(String name) {
2189 2188 if (name == null) {
2190 2189 return name;
2191 2190 }
2192 2191 if (!name.startsWith("/")) {
2193 2192 Class<?> c = this;
2194 2193 while (c.isArray()) {
2195 2194 c = c.getComponentType();
2196 2195 }
2197 2196 String baseName = c.getName();
2198 2197 int index = baseName.lastIndexOf('.');
2199 2198 if (index != -1) {
2200 2199 name = baseName.substring(0, index).replace('.', '/')
2201 2200 +"/"+name;
2202 2201 }
↓ open down ↓ |
1816 lines elided |
↑ open up ↑ |
2203 2202 } else {
2204 2203 name = name.substring(1);
2205 2204 }
2206 2205 return name;
2207 2206 }
2208 2207
2209 2208 /**
2210 2209 * Reflection support.
2211 2210 */
2212 2211
2213 - // Caches for certain reflective results
2212 + // Caches for certain reflective results are stored
2213 + // in an auxiliary helper object - so that we only
2214 + // need allocate them if used
2215 +
2214 2216 private static boolean useCaches = true;
2215 - private volatile transient SoftReference<Field[]> declaredFields;
2216 - private volatile transient SoftReference<Field[]> publicFields;
2217 - private volatile transient SoftReference<Method[]> declaredMethods;
2218 - private volatile transient SoftReference<Method[]> publicMethods;
2219 - private volatile transient SoftReference<Constructor<T>[]> declaredConstructors;
2220 - private volatile transient SoftReference<Constructor<T>[]> publicConstructors;
2221 - // Intermediate results for getFields and getMethods
2222 - private volatile transient SoftReference<Field[]> declaredPublicFields;
2223 - private volatile transient SoftReference<Method[]> declaredPublicMethods;
2224 2217
2218 + // Helper object to hold reflection specific fields
2219 + private volatile transient ReflectionHelper<T> rh;
2220 +
2221 + /**
2222 + * Return a reference to the ReflectionHelper - creating it if necessary
2223 + */
2224 + private ReflectionHelper<T> rh() {
2225 + if (rh == null) {
2226 + synchronized(this) {
2227 + if (rh == null)
2228 + rh = new ReflectionHelper<>();
2229 + }
2230 + }
2231 + return rh;
2232 + }
2233 +
2234 + /**
2235 + * Return a reference to the ReflectionHelper if it exists
2236 + */
2237 + private ReflectionHelper<T> raw_rh() {
2238 + return rh;
2239 + }
2240 +
2241 +
2242 + static class ReflectionHelper<T> {
2243 +
2244 + private transient volatile Constructor<T> cachedConstructor;
2245 + private transient volatile Class<?> newInstanceCallerCache;
2246 +
2247 + private volatile transient SoftReference<Field[]> declaredFields;
2248 + private volatile transient SoftReference<Field[]> publicFields;
2249 + private volatile transient SoftReference<Method[]> declaredMethods;
2250 + private volatile transient SoftReference<Method[]> publicMethods;
2251 + private volatile transient SoftReference<Constructor<T>[]> declaredConstructors;
2252 + private volatile transient SoftReference<Constructor<T>[]> publicConstructors;
2253 + // Intermediate results for getFields and getMethods
2254 + private volatile transient SoftReference<Field[]> declaredPublicFields;
2255 + private volatile transient SoftReference<Method[]> declaredPublicMethods;
2256 +
2257 + private void clearCachesOnClassRedefinition() {
2258 + declaredFields = publicFields = declaredPublicFields = null;
2259 + declaredMethods = publicMethods = declaredPublicMethods = null;
2260 + declaredConstructors = publicConstructors = null;
2261 + }
2262 + }
2263 +
2225 2264 // Incremented by the VM on each call to JVM TI RedefineClasses()
2226 2265 // that redefines this class or a superclass.
2227 2266 private volatile transient int classRedefinedCount = 0;
2228 2267
2229 2268 // Value of classRedefinedCount when we last cleared the cached values
2230 2269 // that are sensitive to class redefinition.
2231 2270 private volatile transient int lastRedefinedCount = 0;
2232 2271
2233 2272 // Clears cached values that might possibly have been obsoleted by
2234 2273 // a class redefinition.
2235 2274 private void clearCachesOnClassRedefinition() {
2236 2275 if (lastRedefinedCount != classRedefinedCount) {
2237 - declaredFields = publicFields = declaredPublicFields = null;
2238 - declaredMethods = publicMethods = declaredPublicMethods = null;
2239 - declaredConstructors = publicConstructors = null;
2276 + // If there's no ReflectionHelper then there is nothing to clear,
2277 + // and we don't want to create the ReflectionHelper unnecessarily
2278 + final ReflectionHelper rh = raw_rh();
2279 + if (rh != null)
2280 + rh.clearCachesOnClassRedefinition();
2281 +
2240 2282 annotations = declaredAnnotations = null;
2241 2283
2242 2284 // Use of "volatile" (and synchronization by caller in the case
2243 2285 // of annotations) ensures that no thread sees the update to
2244 2286 // lastRedefinedCount before seeing the caches cleared.
2245 2287 // We do not guard against brief windows during which multiple
2246 2288 // threads might redundantly work to fill an empty cache.
2247 2289 lastRedefinedCount = classRedefinedCount;
2248 2290 }
2249 2291 }
2250 2292
2251 2293 // Generic signature handling
2252 2294 private native String getGenericSignature();
2253 2295
2254 2296 // Generic info repository; lazily initialized
2255 2297 private transient ClassRepository genericInfo;
2256 2298
2257 2299 // accessor for factory
2258 2300 private GenericsFactory getFactory() {
2259 2301 // create scope and factory
2260 2302 return CoreReflectionFactory.make(this, ClassScope.make(this));
2261 2303 }
2262 2304
2263 2305 // accessor for generic info repository
2264 2306 private ClassRepository getGenericInfo() {
2265 2307 // lazily initialize repository if necessary
2266 2308 if (genericInfo == null) {
2267 2309 // create and cache generic info repository
2268 2310 genericInfo = ClassRepository.make(getGenericSignature(),
2269 2311 getFactory());
2270 2312 }
2271 2313 return genericInfo; //return cached repository
2272 2314 }
2273 2315
2274 2316 // Annotations handling
2275 2317 private native byte[] getRawAnnotations();
2276 2318
2277 2319 native ConstantPool getConstantPool();
2278 2320
2279 2321 //
2280 2322 //
↓ open down ↓ |
31 lines elided |
↑ open up ↑ |
2281 2323 // java.lang.reflect.Field handling
2282 2324 //
2283 2325 //
2284 2326
2285 2327 // Returns an array of "root" fields. These Field objects must NOT
2286 2328 // be propagated to the outside world, but must instead be copied
2287 2329 // via ReflectionFactory.copyField.
2288 2330 private Field[] privateGetDeclaredFields(boolean publicOnly) {
2289 2331 checkInitted();
2290 2332 Field[] res = null;
2333 + final ReflectionHelper<T> rh = rh();
2291 2334 if (useCaches) {
2292 2335 clearCachesOnClassRedefinition();
2293 2336 if (publicOnly) {
2294 - if (declaredPublicFields != null) {
2295 - res = declaredPublicFields.get();
2337 + if (rh.declaredPublicFields != null) {
2338 + res = rh.declaredPublicFields.get();
2296 2339 }
2297 2340 } else {
2298 - if (declaredFields != null) {
2299 - res = declaredFields.get();
2341 + if (rh.declaredFields != null) {
2342 + res = rh.declaredFields.get();
2300 2343 }
2301 2344 }
2302 2345 if (res != null) return res;
2303 2346 }
2304 2347 // No cached value available; request value from VM
2305 2348 res = Reflection.filterFields(this, getDeclaredFields0(publicOnly));
2306 2349 if (useCaches) {
2307 2350 if (publicOnly) {
2308 - declaredPublicFields = new SoftReference<>(res);
2351 + rh.declaredPublicFields = new SoftReference<>(res);
2309 2352 } else {
2310 - declaredFields = new SoftReference<>(res);
2353 + rh.declaredFields = new SoftReference<>(res);
2311 2354 }
2312 2355 }
2313 2356 return res;
2314 2357 }
2315 2358
2316 2359 // Returns an array of "root" fields. These Field objects must NOT
2317 2360 // be propagated to the outside world, but must instead be copied
2318 2361 // via ReflectionFactory.copyField.
2319 2362 private Field[] privateGetPublicFields(Set<Class<?>> traversedInterfaces) {
2320 2363 checkInitted();
2321 2364 Field[] res = null;
2365 + final ReflectionHelper<T> rh = rh();
2322 2366 if (useCaches) {
2323 2367 clearCachesOnClassRedefinition();
2324 - if (publicFields != null) {
2325 - res = publicFields.get();
2368 + if (rh.publicFields != null) {
2369 + res = rh.publicFields.get();
2326 2370 }
2327 2371 if (res != null) return res;
2328 2372 }
2329 2373
2330 2374 // No cached value available; compute value recursively.
2331 2375 // Traverse in correct order for getField().
2332 2376 List<Field> fields = new ArrayList<>();
2333 2377 if (traversedInterfaces == null) {
2334 2378 traversedInterfaces = new HashSet<>();
2335 2379 }
2336 2380
2337 2381 // Local fields
2338 2382 Field[] tmp = privateGetDeclaredFields(true);
2339 2383 addAll(fields, tmp);
2340 2384
2341 2385 // Direct superinterfaces, recursively
2342 2386 for (Class<?> c : getInterfaces()) {
2343 2387 if (!traversedInterfaces.contains(c)) {
2344 2388 traversedInterfaces.add(c);
2345 2389 addAll(fields, c.privateGetPublicFields(traversedInterfaces));
2346 2390 }
2347 2391 }
2348 2392
2349 2393 // Direct superclass, recursively
↓ open down ↓ |
14 lines elided |
↑ open up ↑ |
2350 2394 if (!isInterface()) {
2351 2395 Class<?> c = getSuperclass();
2352 2396 if (c != null) {
2353 2397 addAll(fields, c.privateGetPublicFields(traversedInterfaces));
2354 2398 }
2355 2399 }
2356 2400
2357 2401 res = new Field[fields.size()];
2358 2402 fields.toArray(res);
2359 2403 if (useCaches) {
2360 - publicFields = new SoftReference<>(res);
2404 + rh.publicFields = new SoftReference<>(res);
2361 2405 }
2362 2406 return res;
2363 2407 }
2364 2408
2365 2409 private static void addAll(Collection<Field> c, Field[] o) {
2366 2410 for (int i = 0; i < o.length; i++) {
2367 2411 c.add(o[i]);
2368 2412 }
2369 2413 }
2370 2414
2371 2415
2372 2416 //
2373 2417 //
↓ open down ↓ |
3 lines elided |
↑ open up ↑ |
2374 2418 // java.lang.reflect.Constructor handling
2375 2419 //
2376 2420 //
2377 2421
2378 2422 // Returns an array of "root" constructors. These Constructor
2379 2423 // objects must NOT be propagated to the outside world, but must
2380 2424 // instead be copied via ReflectionFactory.copyConstructor.
2381 2425 private Constructor<T>[] privateGetDeclaredConstructors(boolean publicOnly) {
2382 2426 checkInitted();
2383 2427 Constructor<T>[] res = null;
2428 + final ReflectionHelper<T> rh = rh();
2384 2429 if (useCaches) {
2385 2430 clearCachesOnClassRedefinition();
2386 2431 if (publicOnly) {
2387 - if (publicConstructors != null) {
2388 - res = publicConstructors.get();
2432 + if (rh.publicConstructors != null) {
2433 + res = rh.publicConstructors.get();
2389 2434 }
2390 2435 } else {
2391 - if (declaredConstructors != null) {
2392 - res = declaredConstructors.get();
2436 + if (rh.declaredConstructors != null) {
2437 + res = rh.declaredConstructors.get();
2393 2438 }
2394 2439 }
2395 2440 if (res != null) return res;
2396 2441 }
2397 2442 // No cached value available; request value from VM
2398 2443 if (isInterface()) {
2399 2444 @SuppressWarnings("unchecked")
2400 2445 Constructor<T>[] temporaryRes = (Constructor<T>[]) new Constructor<?>[0];
2401 2446 res = temporaryRes;
2402 2447 } else {
2403 2448 res = getDeclaredConstructors0(publicOnly);
2404 2449 }
2405 2450 if (useCaches) {
2406 2451 if (publicOnly) {
2407 - publicConstructors = new SoftReference<>(res);
2452 + rh.publicConstructors = new SoftReference<>(res);
2408 2453 } else {
2409 - declaredConstructors = new SoftReference<>(res);
2454 + rh.declaredConstructors = new SoftReference<>(res);
2410 2455 }
2411 2456 }
2412 2457 return res;
2413 2458 }
2414 2459
2415 2460 //
2416 2461 //
2417 2462 // java.lang.reflect.Method handling
2418 2463 //
2419 2464 //
2420 2465
2421 2466 // Returns an array of "root" methods. These Method objects must NOT
2422 2467 // be propagated to the outside world, but must instead be copied
2423 2468 // via ReflectionFactory.copyMethod.
2424 2469 private Method[] privateGetDeclaredMethods(boolean publicOnly) {
2425 2470 checkInitted();
2426 2471 Method[] res = null;
2472 + final ReflectionHelper<T> rh = rh();
2427 2473 if (useCaches) {
2428 2474 clearCachesOnClassRedefinition();
2429 2475 if (publicOnly) {
2430 - if (declaredPublicMethods != null) {
2431 - res = declaredPublicMethods.get();
2476 + if (rh.declaredPublicMethods != null) {
2477 + res = rh.declaredPublicMethods.get();
2432 2478 }
2433 2479 } else {
2434 - if (declaredMethods != null) {
2435 - res = declaredMethods.get();
2480 + if (rh.declaredMethods != null) {
2481 + res = rh.declaredMethods.get();
2436 2482 }
2437 2483 }
2438 2484 if (res != null) return res;
2439 2485 }
2440 2486 // No cached value available; request value from VM
2441 2487 res = Reflection.filterMethods(this, getDeclaredMethods0(publicOnly));
2442 2488 if (useCaches) {
2443 2489 if (publicOnly) {
2444 - declaredPublicMethods = new SoftReference<>(res);
2490 + rh.declaredPublicMethods = new SoftReference<>(res);
2445 2491 } else {
2446 - declaredMethods = new SoftReference<>(res);
2492 + rh.declaredMethods = new SoftReference<>(res);
2447 2493 }
2448 2494 }
2449 2495 return res;
2450 2496 }
2451 2497
2452 2498 static class MethodArray {
2453 2499 private Method[] methods;
2454 2500 private int length;
2455 2501
2456 2502 MethodArray() {
2457 2503 methods = new Method[20];
2458 2504 length = 0;
2459 2505 }
2460 2506
2461 2507 void add(Method m) {
2462 2508 if (length == methods.length) {
2463 2509 methods = Arrays.copyOf(methods, 2 * methods.length);
2464 2510 }
2465 2511 methods[length++] = m;
2466 2512 }
2467 2513
2468 2514 void addAll(Method[] ma) {
2469 2515 for (int i = 0; i < ma.length; i++) {
2470 2516 add(ma[i]);
2471 2517 }
2472 2518 }
2473 2519
2474 2520 void addAll(MethodArray ma) {
2475 2521 for (int i = 0; i < ma.length(); i++) {
2476 2522 add(ma.get(i));
2477 2523 }
2478 2524 }
2479 2525
2480 2526 void addIfNotPresent(Method newMethod) {
2481 2527 for (int i = 0; i < length; i++) {
2482 2528 Method m = methods[i];
2483 2529 if (m == newMethod || (m != null && m.equals(newMethod))) {
2484 2530 return;
2485 2531 }
2486 2532 }
2487 2533 add(newMethod);
2488 2534 }
2489 2535
2490 2536 void addAllIfNotPresent(MethodArray newMethods) {
2491 2537 for (int i = 0; i < newMethods.length(); i++) {
2492 2538 Method m = newMethods.get(i);
2493 2539 if (m != null) {
2494 2540 addIfNotPresent(m);
2495 2541 }
2496 2542 }
2497 2543 }
2498 2544
2499 2545 int length() {
2500 2546 return length;
2501 2547 }
2502 2548
2503 2549 Method get(int i) {
2504 2550 return methods[i];
2505 2551 }
2506 2552
2507 2553 void removeByNameAndSignature(Method toRemove) {
2508 2554 for (int i = 0; i < length; i++) {
2509 2555 Method m = methods[i];
2510 2556 if (m != null &&
2511 2557 m.getReturnType() == toRemove.getReturnType() &&
2512 2558 m.getName() == toRemove.getName() &&
2513 2559 arrayContentsEq(m.getParameterTypes(),
2514 2560 toRemove.getParameterTypes())) {
2515 2561 methods[i] = null;
2516 2562 }
2517 2563 }
2518 2564 }
2519 2565
2520 2566 void compactAndTrim() {
2521 2567 int newPos = 0;
2522 2568 // Get rid of null slots
2523 2569 for (int pos = 0; pos < length; pos++) {
2524 2570 Method m = methods[pos];
2525 2571 if (m != null) {
2526 2572 if (pos != newPos) {
2527 2573 methods[newPos] = m;
2528 2574 }
2529 2575 newPos++;
2530 2576 }
2531 2577 }
2532 2578 if (newPos != methods.length) {
2533 2579 methods = Arrays.copyOf(methods, newPos);
2534 2580 }
2535 2581 }
2536 2582
2537 2583 Method[] getArray() {
2538 2584 return methods;
↓ open down ↓ |
82 lines elided |
↑ open up ↑ |
2539 2585 }
2540 2586 }
2541 2587
2542 2588
2543 2589 // Returns an array of "root" methods. These Method objects must NOT
2544 2590 // be propagated to the outside world, but must instead be copied
2545 2591 // via ReflectionFactory.copyMethod.
2546 2592 private Method[] privateGetPublicMethods() {
2547 2593 checkInitted();
2548 2594 Method[] res = null;
2595 + final ReflectionHelper<T> rh = rh();
2549 2596 if (useCaches) {
2550 2597 clearCachesOnClassRedefinition();
2551 - if (publicMethods != null) {
2552 - res = publicMethods.get();
2598 + if (rh.publicMethods != null) {
2599 + res = rh.publicMethods.get();
2553 2600 }
2554 2601 if (res != null) return res;
2555 2602 }
2556 2603
2557 2604 // No cached value available; compute value recursively.
2558 2605 // Start by fetching public declared methods
2559 2606 MethodArray methods = new MethodArray();
2560 2607 {
2561 2608 Method[] tmp = privateGetDeclaredMethods(true);
2562 2609 methods.addAll(tmp);
2563 2610 }
2564 2611 // Now recur over superclass and direct superinterfaces.
2565 2612 // Go over superinterfaces first so we can more easily filter
2566 2613 // out concrete implementations inherited from superclasses at
2567 2614 // the end.
2568 2615 MethodArray inheritedMethods = new MethodArray();
2569 2616 Class<?>[] interfaces = getInterfaces();
2570 2617 for (int i = 0; i < interfaces.length; i++) {
2571 2618 inheritedMethods.addAll(interfaces[i].privateGetPublicMethods());
2572 2619 }
2573 2620 if (!isInterface()) {
2574 2621 Class<?> c = getSuperclass();
2575 2622 if (c != null) {
2576 2623 MethodArray supers = new MethodArray();
2577 2624 supers.addAll(c.privateGetPublicMethods());
2578 2625 // Filter out concrete implementations of any
2579 2626 // interface methods
2580 2627 for (int i = 0; i < supers.length(); i++) {
2581 2628 Method m = supers.get(i);
2582 2629 if (m != null && !Modifier.isAbstract(m.getModifiers())) {
2583 2630 inheritedMethods.removeByNameAndSignature(m);
2584 2631 }
2585 2632 }
2586 2633 // Insert superclass's inherited methods before
2587 2634 // superinterfaces' to satisfy getMethod's search
2588 2635 // order
2589 2636 supers.addAll(inheritedMethods);
2590 2637 inheritedMethods = supers;
2591 2638 }
↓ open down ↓ |
29 lines elided |
↑ open up ↑ |
2592 2639 }
2593 2640 // Filter out all local methods from inherited ones
2594 2641 for (int i = 0; i < methods.length(); i++) {
2595 2642 Method m = methods.get(i);
2596 2643 inheritedMethods.removeByNameAndSignature(m);
2597 2644 }
2598 2645 methods.addAllIfNotPresent(inheritedMethods);
2599 2646 methods.compactAndTrim();
2600 2647 res = methods.getArray();
2601 2648 if (useCaches) {
2602 - publicMethods = new SoftReference<>(res);
2649 + rh.publicMethods = new SoftReference<>(res);
2603 2650 }
2604 2651 return res;
2605 2652 }
2606 2653
2607 2654
2608 2655 //
2609 2656 // Helpers for fetchers of one field, method, or constructor
2610 2657 //
2611 2658
2612 2659 private Field searchFields(Field[] fields, String name) {
2613 2660 String internedName = name.intern();
2614 2661 for (int i = 0; i < fields.length; i++) {
2615 2662 if (fields[i].getName() == internedName) {
2616 2663 return getReflectionFactory().copyField(fields[i]);
2617 2664 }
2618 2665 }
2619 2666 return null;
2620 2667 }
2621 2668
2622 2669 private Field getField0(String name) throws NoSuchFieldException {
2623 2670 // Note: the intent is that the search algorithm this routine
2624 2671 // uses be equivalent to the ordering imposed by
2625 2672 // privateGetPublicFields(). It fetches only the declared
2626 2673 // public fields for each class, however, to reduce the number
2627 2674 // of Field objects which have to be created for the common
2628 2675 // case where the field being requested is declared in the
2629 2676 // class which is being queried.
2630 2677 Field res = null;
2631 2678 // Search declared public fields
2632 2679 if ((res = searchFields(privateGetDeclaredFields(true), name)) != null) {
2633 2680 return res;
2634 2681 }
2635 2682 // Direct superinterfaces, recursively
2636 2683 Class<?>[] interfaces = getInterfaces();
2637 2684 for (int i = 0; i < interfaces.length; i++) {
2638 2685 Class<?> c = interfaces[i];
2639 2686 if ((res = c.getField0(name)) != null) {
2640 2687 return res;
2641 2688 }
2642 2689 }
2643 2690 // Direct superclass, recursively
2644 2691 if (!isInterface()) {
2645 2692 Class<?> c = getSuperclass();
2646 2693 if (c != null) {
2647 2694 if ((res = c.getField0(name)) != null) {
2648 2695 return res;
2649 2696 }
2650 2697 }
2651 2698 }
2652 2699 return null;
2653 2700 }
2654 2701
2655 2702 private static Method searchMethods(Method[] methods,
2656 2703 String name,
2657 2704 Class<?>[] parameterTypes)
2658 2705 {
2659 2706 Method res = null;
2660 2707 String internedName = name.intern();
2661 2708 for (int i = 0; i < methods.length; i++) {
2662 2709 Method m = methods[i];
2663 2710 if (m.getName() == internedName
2664 2711 && arrayContentsEq(parameterTypes, m.getParameterTypes())
2665 2712 && (res == null
2666 2713 || res.getReturnType().isAssignableFrom(m.getReturnType())))
2667 2714 res = m;
2668 2715 }
2669 2716
2670 2717 return (res == null ? res : getReflectionFactory().copyMethod(res));
2671 2718 }
2672 2719
2673 2720
2674 2721 private Method getMethod0(String name, Class<?>[] parameterTypes) {
2675 2722 // Note: the intent is that the search algorithm this routine
2676 2723 // uses be equivalent to the ordering imposed by
2677 2724 // privateGetPublicMethods(). It fetches only the declared
2678 2725 // public methods for each class, however, to reduce the
2679 2726 // number of Method objects which have to be created for the
2680 2727 // common case where the method being requested is declared in
2681 2728 // the class which is being queried.
2682 2729 Method res = null;
2683 2730 // Search declared public methods
2684 2731 if ((res = searchMethods(privateGetDeclaredMethods(true),
2685 2732 name,
2686 2733 parameterTypes)) != null) {
2687 2734 return res;
2688 2735 }
2689 2736 // Search superclass's methods
2690 2737 if (!isInterface()) {
2691 2738 Class<? super T> c = getSuperclass();
2692 2739 if (c != null) {
2693 2740 if ((res = c.getMethod0(name, parameterTypes)) != null) {
2694 2741 return res;
2695 2742 }
2696 2743 }
2697 2744 }
2698 2745 // Search superinterfaces' methods
2699 2746 Class<?>[] interfaces = getInterfaces();
2700 2747 for (int i = 0; i < interfaces.length; i++) {
2701 2748 Class<?> c = interfaces[i];
2702 2749 if ((res = c.getMethod0(name, parameterTypes)) != null) {
2703 2750 return res;
2704 2751 }
2705 2752 }
2706 2753 // Not found
2707 2754 return null;
2708 2755 }
2709 2756
2710 2757 private Constructor<T> getConstructor0(Class<?>[] parameterTypes,
2711 2758 int which) throws NoSuchMethodException
2712 2759 {
2713 2760 Constructor<T>[] constructors = privateGetDeclaredConstructors((which == Member.PUBLIC));
2714 2761 for (Constructor<T> constructor : constructors) {
2715 2762 if (arrayContentsEq(parameterTypes,
2716 2763 constructor.getParameterTypes())) {
2717 2764 return getReflectionFactory().copyConstructor(constructor);
2718 2765 }
2719 2766 }
2720 2767 throw new NoSuchMethodException(getName() + ".<init>" + argumentTypesToString(parameterTypes));
2721 2768 }
2722 2769
2723 2770 //
2724 2771 // Other helpers and base implementation
2725 2772 //
2726 2773
2727 2774 private static boolean arrayContentsEq(Object[] a1, Object[] a2) {
2728 2775 if (a1 == null) {
2729 2776 return a2 == null || a2.length == 0;
2730 2777 }
2731 2778
2732 2779 if (a2 == null) {
2733 2780 return a1.length == 0;
2734 2781 }
2735 2782
2736 2783 if (a1.length != a2.length) {
2737 2784 return false;
2738 2785 }
2739 2786
2740 2787 for (int i = 0; i < a1.length; i++) {
2741 2788 if (a1[i] != a2[i]) {
2742 2789 return false;
2743 2790 }
2744 2791 }
2745 2792
2746 2793 return true;
2747 2794 }
2748 2795
2749 2796 private static Field[] copyFields(Field[] arg) {
2750 2797 Field[] out = new Field[arg.length];
2751 2798 ReflectionFactory fact = getReflectionFactory();
2752 2799 for (int i = 0; i < arg.length; i++) {
2753 2800 out[i] = fact.copyField(arg[i]);
2754 2801 }
2755 2802 return out;
2756 2803 }
2757 2804
2758 2805 private static Method[] copyMethods(Method[] arg) {
2759 2806 Method[] out = new Method[arg.length];
2760 2807 ReflectionFactory fact = getReflectionFactory();
2761 2808 for (int i = 0; i < arg.length; i++) {
2762 2809 out[i] = fact.copyMethod(arg[i]);
2763 2810 }
2764 2811 return out;
2765 2812 }
2766 2813
2767 2814 private static <U> Constructor<U>[] copyConstructors(Constructor<U>[] arg) {
2768 2815 Constructor<U>[] out = arg.clone();
2769 2816 ReflectionFactory fact = getReflectionFactory();
2770 2817 for (int i = 0; i < out.length; i++) {
2771 2818 out[i] = fact.copyConstructor(out[i]);
2772 2819 }
2773 2820 return out;
2774 2821 }
2775 2822
2776 2823 private native Field[] getDeclaredFields0(boolean publicOnly);
2777 2824 private native Method[] getDeclaredMethods0(boolean publicOnly);
2778 2825 private native Constructor<T>[] getDeclaredConstructors0(boolean publicOnly);
2779 2826 private native Class<?>[] getDeclaredClasses0();
2780 2827
2781 2828 private static String argumentTypesToString(Class<?>[] argTypes) {
2782 2829 StringBuilder buf = new StringBuilder();
2783 2830 buf.append("(");
2784 2831 if (argTypes != null) {
2785 2832 for (int i = 0; i < argTypes.length; i++) {
2786 2833 if (i > 0) {
2787 2834 buf.append(", ");
2788 2835 }
2789 2836 Class<?> c = argTypes[i];
2790 2837 buf.append((c == null) ? "null" : c.getName());
2791 2838 }
2792 2839 }
2793 2840 buf.append(")");
2794 2841 return buf.toString();
2795 2842 }
2796 2843
2797 2844 /** use serialVersionUID from JDK 1.1 for interoperability */
2798 2845 private static final long serialVersionUID = 3206093459760846163L;
2799 2846
2800 2847
2801 2848 /**
2802 2849 * Class Class is special cased within the Serialization Stream Protocol.
2803 2850 *
2804 2851 * A Class instance is written initially into an ObjectOutputStream in the
2805 2852 * following format:
2806 2853 * <pre>
2807 2854 * {@code TC_CLASS} ClassDescriptor
2808 2855 * A ClassDescriptor is a special cased serialization of
2809 2856 * a {@code java.io.ObjectStreamClass} instance.
2810 2857 * </pre>
2811 2858 * A new handle is generated for the initial time the class descriptor
2812 2859 * is written into the stream. Future references to the class descriptor
2813 2860 * are written as references to the initial class descriptor instance.
2814 2861 *
2815 2862 * @see java.io.ObjectStreamClass
2816 2863 */
2817 2864 private static final ObjectStreamField[] serialPersistentFields =
2818 2865 new ObjectStreamField[0];
2819 2866
2820 2867
2821 2868 /**
2822 2869 * Returns the assertion status that would be assigned to this
2823 2870 * class if it were to be initialized at the time this method is invoked.
2824 2871 * If this class has had its assertion status set, the most recent
2825 2872 * setting will be returned; otherwise, if any package default assertion
2826 2873 * status pertains to this class, the most recent setting for the most
2827 2874 * specific pertinent package default assertion status is returned;
2828 2875 * otherwise, if this class is not a system class (i.e., it has a
2829 2876 * class loader) its class loader's default assertion status is returned;
2830 2877 * otherwise, the system class default assertion status is returned.
2831 2878 * <p>
2832 2879 * Few programmers will have any need for this method; it is provided
2833 2880 * for the benefit of the JRE itself. (It allows a class to determine at
2834 2881 * the time that it is initialized whether assertions should be enabled.)
2835 2882 * Note that this method is not guaranteed to return the actual
2836 2883 * assertion status that was (or will be) associated with the specified
2837 2884 * class when it was (or will be) initialized.
2838 2885 *
2839 2886 * @return the desired assertion status of the specified class.
2840 2887 * @see java.lang.ClassLoader#setClassAssertionStatus
2841 2888 * @see java.lang.ClassLoader#setPackageAssertionStatus
2842 2889 * @see java.lang.ClassLoader#setDefaultAssertionStatus
2843 2890 * @since 1.4
2844 2891 */
2845 2892 public boolean desiredAssertionStatus() {
2846 2893 ClassLoader loader = getClassLoader();
2847 2894 // If the loader is null this is a system class, so ask the VM
2848 2895 if (loader == null)
2849 2896 return desiredAssertionStatus0(this);
2850 2897
2851 2898 // If the classloader has been initialized with the assertion
2852 2899 // directives, ask it. Otherwise, ask the VM.
2853 2900 synchronized(loader.assertionLock) {
2854 2901 if (loader.classAssertionStatus != null) {
2855 2902 return loader.desiredAssertionStatus(getName());
2856 2903 }
2857 2904 }
2858 2905 return desiredAssertionStatus0(this);
2859 2906 }
2860 2907
2861 2908 // Retrieves the desired assertion status of this class from the VM
2862 2909 private static native boolean desiredAssertionStatus0(Class<?> clazz);
2863 2910
2864 2911 /**
2865 2912 * Returns true if and only if this class was declared as an enum in the
2866 2913 * source code.
2867 2914 *
2868 2915 * @return true if and only if this class was declared as an enum in the
2869 2916 * source code
2870 2917 * @since 1.5
2871 2918 */
2872 2919 public boolean isEnum() {
2873 2920 // An enum must both directly extend java.lang.Enum and have
2874 2921 // the ENUM bit set; classes for specialized enum constants
2875 2922 // don't do the former.
2876 2923 return (this.getModifiers() & ENUM) != 0 &&
2877 2924 this.getSuperclass() == java.lang.Enum.class;
2878 2925 }
2879 2926
2880 2927 // Fetches the factory for reflective objects
2881 2928 private static ReflectionFactory getReflectionFactory() {
2882 2929 if (reflectionFactory == null) {
2883 2930 reflectionFactory =
2884 2931 java.security.AccessController.doPrivileged
2885 2932 (new sun.reflect.ReflectionFactory.GetReflectionFactoryAction());
2886 2933 }
2887 2934 return reflectionFactory;
2888 2935 }
2889 2936 private static ReflectionFactory reflectionFactory;
2890 2937
2891 2938 // To be able to query system properties as soon as they're available
2892 2939 private static boolean initted = false;
2893 2940 private static void checkInitted() {
2894 2941 if (initted) return;
2895 2942 AccessController.doPrivileged(new PrivilegedAction<Void>() {
2896 2943 public Void run() {
2897 2944 // Tests to ensure the system properties table is fully
2898 2945 // initialized. This is needed because reflection code is
2899 2946 // called very early in the initialization process (before
2900 2947 // command-line arguments have been parsed and therefore
2901 2948 // these user-settable properties installed.) We assume that
2902 2949 // if System.out is non-null then the System class has been
2903 2950 // fully initialized and that the bulk of the startup code
2904 2951 // has been run.
2905 2952
2906 2953 if (System.out == null) {
2907 2954 // java.lang.System not yet fully initialized
2908 2955 return null;
2909 2956 }
2910 2957
2911 2958 // Doesn't use Boolean.getBoolean to avoid class init.
2912 2959 String val =
2913 2960 System.getProperty("sun.reflect.noCaches");
2914 2961 if (val != null && val.equals("true")) {
2915 2962 useCaches = false;
2916 2963 }
2917 2964
2918 2965 initted = true;
2919 2966 return null;
2920 2967 }
2921 2968 });
2922 2969 }
2923 2970
2924 2971 /**
2925 2972 * Returns the elements of this enum class or null if this
2926 2973 * Class object does not represent an enum type.
2927 2974 *
2928 2975 * @return an array containing the values comprising the enum class
2929 2976 * represented by this Class object in the order they're
2930 2977 * declared, or null if this Class object does not
2931 2978 * represent an enum type
2932 2979 * @since 1.5
2933 2980 */
2934 2981 public T[] getEnumConstants() {
2935 2982 T[] values = getEnumConstantsShared();
2936 2983 return (values != null) ? values.clone() : null;
2937 2984 }
2938 2985
2939 2986 /**
2940 2987 * Returns the elements of this enum class or null if this
2941 2988 * Class object does not represent an enum type;
2942 2989 * identical to getEnumConstants except that the result is
2943 2990 * uncloned, cached, and shared by all callers.
2944 2991 */
2945 2992 T[] getEnumConstantsShared() {
2946 2993 if (enumConstants == null) {
2947 2994 if (!isEnum()) return null;
2948 2995 try {
2949 2996 final Method values = getMethod("values");
2950 2997 java.security.AccessController.doPrivileged(
2951 2998 new java.security.PrivilegedAction<Void>() {
2952 2999 public Void run() {
2953 3000 values.setAccessible(true);
2954 3001 return null;
2955 3002 }
2956 3003 });
2957 3004 @SuppressWarnings("unchecked")
2958 3005 T[] temporaryConstants = (T[])values.invoke(null);
2959 3006 enumConstants = temporaryConstants;
2960 3007 }
2961 3008 // These can happen when users concoct enum-like classes
2962 3009 // that don't comply with the enum spec.
2963 3010 catch (InvocationTargetException | NoSuchMethodException |
2964 3011 IllegalAccessException ex) { return null; }
2965 3012 }
2966 3013 return enumConstants;
2967 3014 }
2968 3015 private volatile transient T[] enumConstants = null;
2969 3016
2970 3017 /**
2971 3018 * Returns a map from simple name to enum constant. This package-private
2972 3019 * method is used internally by Enum to implement
2973 3020 * public static <T extends Enum<T>> T valueOf(Class<T>, String)
2974 3021 * efficiently. Note that the map is returned by this method is
2975 3022 * created lazily on first use. Typically it won't ever get created.
2976 3023 */
2977 3024 Map<String, T> enumConstantDirectory() {
2978 3025 if (enumConstantDirectory == null) {
2979 3026 T[] universe = getEnumConstantsShared();
2980 3027 if (universe == null)
2981 3028 throw new IllegalArgumentException(
2982 3029 getName() + " is not an enum type");
2983 3030 Map<String, T> m = new HashMap<>(2 * universe.length);
2984 3031 for (T constant : universe)
2985 3032 m.put(((Enum<?>)constant).name(), constant);
2986 3033 enumConstantDirectory = m;
2987 3034 }
2988 3035 return enumConstantDirectory;
2989 3036 }
2990 3037 private volatile transient Map<String, T> enumConstantDirectory = null;
2991 3038
2992 3039 /**
2993 3040 * Casts an object to the class or interface represented
2994 3041 * by this {@code Class} object.
2995 3042 *
2996 3043 * @param obj the object to be cast
2997 3044 * @return the object after casting, or null if obj is null
2998 3045 *
2999 3046 * @throws ClassCastException if the object is not
3000 3047 * null and is not assignable to the type T.
3001 3048 *
3002 3049 * @since 1.5
3003 3050 */
3004 3051 @SuppressWarnings("unchecked")
3005 3052 public T cast(Object obj) {
3006 3053 if (obj != null && !isInstance(obj))
3007 3054 throw new ClassCastException(cannotCastMsg(obj));
3008 3055 return (T) obj;
3009 3056 }
3010 3057
3011 3058 private String cannotCastMsg(Object obj) {
3012 3059 return "Cannot cast " + obj.getClass().getName() + " to " + getName();
3013 3060 }
3014 3061
3015 3062 /**
3016 3063 * Casts this {@code Class} object to represent a subclass of the class
3017 3064 * represented by the specified class object. Checks that the cast
3018 3065 * is valid, and throws a {@code ClassCastException} if it is not. If
3019 3066 * this method succeeds, it always returns a reference to this class object.
3020 3067 *
3021 3068 * <p>This method is useful when a client needs to "narrow" the type of
3022 3069 * a {@code Class} object to pass it to an API that restricts the
3023 3070 * {@code Class} objects that it is willing to accept. A cast would
3024 3071 * generate a compile-time warning, as the correctness of the cast
3025 3072 * could not be checked at runtime (because generic types are implemented
3026 3073 * by erasure).
3027 3074 *
3028 3075 * @return this {@code Class} object, cast to represent a subclass of
3029 3076 * the specified class object.
3030 3077 * @throws ClassCastException if this {@code Class} object does not
3031 3078 * represent a subclass of the specified class (here "subclass" includes
3032 3079 * the class itself).
3033 3080 * @since 1.5
3034 3081 */
3035 3082 @SuppressWarnings("unchecked")
3036 3083 public <U> Class<? extends U> asSubclass(Class<U> clazz) {
3037 3084 if (clazz.isAssignableFrom(this))
3038 3085 return (Class<? extends U>) this;
3039 3086 else
3040 3087 throw new ClassCastException(this.toString());
3041 3088 }
3042 3089
3043 3090 /**
3044 3091 * @throws NullPointerException {@inheritDoc}
3045 3092 * @since 1.5
3046 3093 */
3047 3094 @SuppressWarnings("unchecked")
3048 3095 public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {
3049 3096 if (annotationClass == null)
3050 3097 throw new NullPointerException();
3051 3098
3052 3099 initAnnotationsIfNecessary();
3053 3100 return (A) annotations.get(annotationClass);
3054 3101 }
3055 3102
3056 3103 /**
3057 3104 * @throws NullPointerException {@inheritDoc}
3058 3105 * @since 1.5
3059 3106 */
3060 3107 public boolean isAnnotationPresent(
3061 3108 Class<? extends Annotation> annotationClass) {
3062 3109 if (annotationClass == null)
3063 3110 throw new NullPointerException();
3064 3111
3065 3112 return getAnnotation(annotationClass) != null;
3066 3113 }
3067 3114
3068 3115
3069 3116 /**
3070 3117 * @since 1.5
3071 3118 */
3072 3119 public Annotation[] getAnnotations() {
3073 3120 initAnnotationsIfNecessary();
3074 3121 return AnnotationParser.toArray(annotations);
3075 3122 }
3076 3123
3077 3124 /**
3078 3125 * @since 1.5
3079 3126 */
3080 3127 public Annotation[] getDeclaredAnnotations() {
3081 3128 initAnnotationsIfNecessary();
3082 3129 return AnnotationParser.toArray(declaredAnnotations);
3083 3130 }
3084 3131
3085 3132 // Annotations cache
3086 3133 private transient Map<Class<? extends Annotation>, Annotation> annotations;
3087 3134 private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
3088 3135
3089 3136 private synchronized void initAnnotationsIfNecessary() {
3090 3137 clearCachesOnClassRedefinition();
3091 3138 if (annotations != null)
3092 3139 return;
3093 3140 declaredAnnotations = AnnotationParser.parseAnnotations(
3094 3141 getRawAnnotations(), getConstantPool(), this);
3095 3142 Class<?> superClass = getSuperclass();
3096 3143 if (superClass == null) {
3097 3144 annotations = declaredAnnotations;
3098 3145 } else {
3099 3146 annotations = new HashMap<>();
3100 3147 superClass.initAnnotationsIfNecessary();
3101 3148 for (Map.Entry<Class<? extends Annotation>, Annotation> e : superClass.annotations.entrySet()) {
3102 3149 Class<? extends Annotation> annotationClass = e.getKey();
3103 3150 if (AnnotationType.getInstance(annotationClass).isInherited())
3104 3151 annotations.put(annotationClass, e.getValue());
3105 3152 }
3106 3153 annotations.putAll(declaredAnnotations);
3107 3154 }
3108 3155 }
3109 3156
3110 3157 // Annotation types cache their internal (AnnotationType) form
↓ open down ↓ |
498 lines elided |
↑ open up ↑ |
3111 3158
3112 3159 private AnnotationType annotationType;
3113 3160
3114 3161 void setAnnotationType(AnnotationType type) {
3115 3162 annotationType = type;
3116 3163 }
3117 3164
3118 3165 AnnotationType getAnnotationType() {
3119 3166 return annotationType;
3120 3167 }
3168 +
3121 3169 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX