In order to support fields of the same name in subclasses we are now prefixing them with name of the class that defines them. To provide convenient way to access them from generated bytecode and also directly from JavaScript, there is a getter/setter function for each field. It starts with _ followed by the field name. If called with a parameter, it sets the field, with a parameter it just returns it.
2 * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
28 import java.io.ByteArrayInputStream;
29 import org.apidesign.bck2brwsr.emul.reflect.AnnotationImpl;
30 import java.io.InputStream;
31 import java.lang.annotation.Annotation;
32 import java.lang.reflect.Field;
33 import java.lang.reflect.Method;
34 import java.lang.reflect.TypeVariable;
36 import org.apidesign.bck2brwsr.core.JavaScriptBody;
37 import org.apidesign.bck2brwsr.emul.reflect.MethodImpl;
40 * Instances of the class {@code Class} represent classes and
41 * interfaces in a running Java application. An enum is a kind of
42 * class and an annotation is a kind of interface. Every array also
43 * belongs to a class that is reflected as a {@code Class} object
44 * that is shared by all arrays with the same element type and number
45 * of dimensions. The primitive Java types ({@code boolean},
46 * {@code byte}, {@code char}, {@code short},
47 * {@code int}, {@code long}, {@code float}, and
48 * {@code double}), and the keyword {@code void} are also
49 * represented as {@code Class} objects.
51 * <p> {@code Class} has no public constructor. Instead {@code Class}
52 * objects are constructed automatically by the Java Virtual Machine as classes
53 * are loaded and by calls to the {@code defineClass} method in the class
56 * <p> The following example uses a {@code Class} object to print the
57 * class name of an object:
59 * <p> <blockquote><pre>
60 * void printClassName(Object obj) {
61 * System.out.println("The class of " + obj +
62 * " is " + obj.getClass().getName());
66 * <p> It is also possible to get the {@code Class} object for a named
67 * type (or for void) using a class literal. See Section 15.8.2 of
68 * <cite>The Java™ Language Specification</cite>.
72 * {@code System.out.println("The name of class Foo is: "+Foo.class.getName());}
75 * @param <T> the type of the class modeled by this {@code Class}
76 * object. For example, the type of {@code String.class} is {@code
77 * Class<String>}. Use {@code Class<?>} if the class being modeled is
81 * @see java.lang.ClassLoader#defineClass(byte[], int, int)
85 class Class<T> implements java.io.Serializable,
86 java.lang.reflect.GenericDeclaration,
87 java.lang.reflect.Type,
88 java.lang.reflect.AnnotatedElement {
89 private static final int ANNOTATION= 0x00002000;
90 private static final int ENUM = 0x00004000;
91 private static final int SYNTHETIC = 0x00001000;
94 * Constructor. Only the Java Virtual Machine creates Class
101 * Converts the object to a string. The string representation is the
102 * string "class" or "interface", followed by a space, and then by the
103 * fully qualified name of the class in the format returned by
104 * {@code getName}. If this {@code Class} object represents a
105 * primitive type, this method returns the name of the primitive type. If
106 * this {@code Class} object represents void this method returns
109 * @return a string representation of this class object.
111 public String toString() {
112 return (isInterface() ? "interface " : (isPrimitive() ? "" : "class "))
118 * Returns the {@code Class} object associated with the class or
119 * interface with the given string name. Invoking this method is
123 * {@code Class.forName(className, true, currentLoader)}
126 * where {@code currentLoader} denotes the defining class loader of
129 * <p> For example, the following code fragment returns the
130 * runtime {@code Class} descriptor for the class named
131 * {@code java.lang.Thread}:
134 * {@code Class t = Class.forName("java.lang.Thread")}
137 * A call to {@code forName("X")} causes the class named
138 * {@code X} to be initialized.
140 * @param className the fully qualified name of the desired class.
141 * @return the {@code Class} object for the class with the
143 * @exception LinkageError if the linkage fails
144 * @exception ExceptionInInitializerError if the initialization provoked
145 * by this method fails
146 * @exception ClassNotFoundException if the class cannot be located
148 public static Class<?> forName(String className)
149 throws ClassNotFoundException {
150 if (className.startsWith("[")) {
151 Class<?> arrType = defineArray(className);
152 Class<?> c = arrType;
153 while (c != null && c.isArray()) {
154 c = c.getComponentType0(); // verify component type is sane
158 Class<?> c = loadCls(className, className.replace('.', '_'));
160 throw new ClassNotFoundException(className);
167 * Returns the {@code Class} object associated with the class or
168 * interface with the given string name, using the given class loader.
169 * Given the fully qualified name for a class or interface (in the same
170 * format returned by {@code getName}) this method attempts to
171 * locate, load, and link the class or interface. The specified class
172 * loader is used to load the class or interface. If the parameter
173 * {@code loader} is null, the class is loaded through the bootstrap
174 * class loader. The class is initialized only if the
175 * {@code initialize} parameter is {@code true} and if it has
176 * not been initialized earlier.
178 * <p> If {@code name} denotes a primitive type or void, an attempt
179 * will be made to locate a user-defined class in the unnamed package whose
180 * name is {@code name}. Therefore, this method cannot be used to
181 * obtain any of the {@code Class} objects representing primitive
184 * <p> If {@code name} denotes an array class, the component type of
185 * the array class is loaded but not initialized.
187 * <p> For example, in an instance method the expression:
190 * {@code Class.forName("Foo")}
196 * {@code Class.forName("Foo", true, this.getClass().getClassLoader())}
199 * Note that this method throws errors related to loading, linking or
200 * initializing as specified in Sections 12.2, 12.3 and 12.4 of <em>The
201 * Java Language Specification</em>.
202 * Note that this method does not check whether the requested class
203 * is accessible to its caller.
205 * <p> If the {@code loader} is {@code null}, and a security
206 * manager is present, and the caller's class loader is not null, then this
207 * method calls the security manager's {@code checkPermission} method
208 * with a {@code RuntimePermission("getClassLoader")} permission to
209 * ensure it's ok to access the bootstrap class loader.
211 * @param name fully qualified name of the desired class
212 * @param initialize whether the class must be initialized
213 * @param loader class loader from which the class must be loaded
214 * @return class object representing the desired class
216 * @exception LinkageError if the linkage fails
217 * @exception ExceptionInInitializerError if the initialization provoked
218 * by this method fails
219 * @exception ClassNotFoundException if the class cannot be located by
220 * the specified class loader
222 * @see java.lang.Class#forName(String)
223 * @see java.lang.ClassLoader
226 public static Class<?> forName(String name, boolean initialize,
228 throws ClassNotFoundException
230 return forName(name);
233 @JavaScriptBody(args = {"n", "c" }, body =
234 "if (vm[c]) return vm[c].$class;\n"
235 + "if (vm.loadClass) {\n"
236 + " vm.loadClass(n);\n"
237 + " if (vm[c]) return vm[c].$class;\n"
241 private static native Class<?> loadCls(String n, String c);
245 * Creates a new instance of the class represented by this {@code Class}
246 * object. The class is instantiated as if by a {@code new}
247 * expression with an empty argument list. The class is initialized if it
248 * has not already been initialized.
250 * <p>Note that this method propagates any exception thrown by the
251 * nullary constructor, including a checked exception. Use of
252 * this method effectively bypasses the compile-time exception
253 * checking that would otherwise be performed by the compiler.
255 * java.lang.reflect.Constructor#newInstance(java.lang.Object...)
256 * Constructor.newInstance} method avoids this problem by wrapping
257 * any exception thrown by the constructor in a (checked) {@link
258 * java.lang.reflect.InvocationTargetException}.
260 * @return a newly allocated instance of the class represented by this
262 * @exception IllegalAccessException if the class or its nullary
263 * constructor is not accessible.
264 * @exception InstantiationException
265 * if this {@code Class} represents an abstract class,
266 * an interface, an array class, a primitive type, or void;
267 * or if the class has no nullary constructor;
268 * or if the instantiation fails for some other reason.
269 * @exception ExceptionInInitializerError if the initialization
270 * provoked by this method fails.
271 * @exception SecurityException
272 * If a security manager, <i>s</i>, is present and any of the
273 * following conditions is met:
278 * {@link SecurityManager#checkMemberAccess
279 * s.checkMemberAccess(this, Member.PUBLIC)} denies
280 * creation of new instances of this class
282 * <li> the caller's class loader is not the same as or an
283 * ancestor of the class loader for the current class and
284 * invocation of {@link SecurityManager#checkPackageAccess
285 * s.checkPackageAccess()} denies access to the package
291 @JavaScriptBody(args = { "self", "illegal" }, body =
292 "\nvar c = self.cnstr;"
293 + "\nif (c['cons__V']) {"
294 + "\n if ((c.cons__V.access & 0x1) != 0) {"
295 + "\n var inst = c();"
296 + "\n c.cons__V.call(inst);"
299 + "\n return illegal;"
303 private static native Object newInstance0(Class<?> self, Object illegal);
305 public T newInstance()
306 throws InstantiationException, IllegalAccessException
308 Object illegal = new Object();
309 Object inst = newInstance0(this, illegal);
311 throw new InstantiationException(getName());
313 if (inst == illegal) {
314 throw new IllegalAccessException();
320 * Determines if the specified {@code Object} is assignment-compatible
321 * with the object represented by this {@code Class}. This method is
322 * the dynamic equivalent of the Java language {@code instanceof}
323 * operator. The method returns {@code true} if the specified
324 * {@code Object} argument is non-null and can be cast to the
325 * reference type represented by this {@code Class} object without
326 * raising a {@code ClassCastException.} It returns {@code false}
329 * <p> Specifically, if this {@code Class} object represents a
330 * declared class, this method returns {@code true} if the specified
331 * {@code Object} argument is an instance of the represented class (or
332 * of any of its subclasses); it returns {@code false} otherwise. If
333 * this {@code Class} object represents an array class, this method
334 * returns {@code true} if the specified {@code Object} argument
335 * can be converted to an object of the array class by an identity
336 * conversion or by a widening reference conversion; it returns
337 * {@code false} otherwise. If this {@code Class} object
338 * represents an interface, this method returns {@code true} if the
339 * class or any superclass of the specified {@code Object} argument
340 * implements this interface; it returns {@code false} otherwise. If
341 * this {@code Class} object represents a primitive type, this method
342 * returns {@code false}.
344 * @param obj the object to check
345 * @return true if {@code obj} is an instance of this class
349 public boolean isInstance(Object obj) {
351 return isAssignableFrom(obj.getClass());
354 String prop = "$instOf_" + getName().replace('.', '_');
355 return hasProperty(obj, prop);
358 @JavaScriptBody(args = { "who", "prop" }, body =
359 "if (who[prop]) return true; else return false;"
361 private static native boolean hasProperty(Object who, String prop);
365 * Determines if the class or interface represented by this
366 * {@code Class} object is either the same as, or is a superclass or
367 * superinterface of, the class or interface represented by the specified
368 * {@code Class} parameter. It returns {@code true} if so;
369 * otherwise it returns {@code false}. If this {@code Class}
370 * object represents a primitive type, this method returns
371 * {@code true} if the specified {@code Class} parameter is
372 * exactly this {@code Class} object; otherwise it returns
375 * <p> Specifically, this method tests whether the type represented by the
376 * specified {@code Class} parameter can be converted to the type
377 * represented by this {@code Class} object via an identity conversion
378 * or via a widening reference conversion. See <em>The Java Language
379 * Specification</em>, sections 5.1.1 and 5.1.4 , for details.
381 * @param cls the {@code Class} object to be checked
382 * @return the {@code boolean} value indicating whether objects of the
383 * type {@code cls} can be assigned to objects of this class
384 * @exception NullPointerException if the specified Class parameter is
388 public boolean isAssignableFrom(Class<?> cls) {
394 final Class<?> cmpType = cls.getComponentType();
396 return this == cmpType;
398 return cmpType != null && getComponentType().isAssignableFrom(cmpType);
400 String prop = "$instOf_" + getName().replace('.', '_');
401 return hasProperty(cls, prop);
406 * Determines if the specified {@code Class} object represents an
409 * @return {@code true} if this object represents an interface;
410 * {@code false} otherwise.
412 public boolean isInterface() {
413 return (getAccess() & 0x200) != 0;
416 @JavaScriptBody(args = {}, body = "return this.access;")
417 private native int getAccess();
421 * Determines if this {@code Class} object represents an array class.
423 * @return {@code true} if this object represents an array class;
424 * {@code false} otherwise.
427 public boolean isArray() {
428 return hasProperty(this, "array"); // NOI18N
433 * Determines if the specified {@code Class} object represents a
436 * <p> There are nine predefined {@code Class} objects to represent
437 * the eight primitive types and void. These are created by the Java
438 * Virtual Machine, and have the same names as the primitive types that
439 * they represent, namely {@code boolean}, {@code byte},
440 * {@code char}, {@code short}, {@code int},
441 * {@code long}, {@code float}, and {@code double}.
443 * <p> These objects may only be accessed via the following public static
444 * final variables, and are the only {@code Class} objects for which
445 * this method returns {@code true}.
447 * @return true if and only if this class represents a primitive type
449 * @see java.lang.Boolean#TYPE
450 * @see java.lang.Character#TYPE
451 * @see java.lang.Byte#TYPE
452 * @see java.lang.Short#TYPE
453 * @see java.lang.Integer#TYPE
454 * @see java.lang.Long#TYPE
455 * @see java.lang.Float#TYPE
456 * @see java.lang.Double#TYPE
457 * @see java.lang.Void#TYPE
460 @JavaScriptBody(args = {}, body =
461 "if (this.primitive) return true;"
462 + "else return false;"
464 public native boolean isPrimitive();
467 * Returns true if this {@code Class} object represents an annotation
468 * type. Note that if this method returns true, {@link #isInterface()}
469 * would also return true, as all annotation types are also interfaces.
471 * @return {@code true} if this class object represents an annotation
472 * type; {@code false} otherwise
475 public boolean isAnnotation() {
476 return (getModifiers() & ANNOTATION) != 0;
480 * Returns {@code true} if this class is a synthetic class;
481 * returns {@code false} otherwise.
482 * @return {@code true} if and only if this class is a synthetic class as
483 * defined by the Java Language Specification.
486 public boolean isSynthetic() {
487 return (getModifiers() & SYNTHETIC) != 0;
491 * Returns the name of the entity (class, interface, array class,
492 * primitive type, or void) represented by this {@code Class} object,
493 * as a {@code String}.
495 * <p> If this class object represents a reference type that is not an
496 * array type then the binary name of the class is returned, as specified
498 * <cite>The Java™ Language Specification</cite>.
500 * <p> If this class object represents a primitive type or void, then the
501 * name returned is a {@code String} equal to the Java language
502 * keyword corresponding to the primitive type or void.
504 * <p> If this class object represents a class of arrays, then the internal
505 * form of the name consists of the name of the element type preceded by
506 * one or more '{@code [}' characters representing the depth of the array
507 * nesting. The encoding of element type names is as follows:
509 * <blockquote><table summary="Element types and encodings">
510 * <tr><th> Element Type <th> <th> Encoding
511 * <tr><td> boolean <td> <td align=center> Z
512 * <tr><td> byte <td> <td align=center> B
513 * <tr><td> char <td> <td align=center> C
514 * <tr><td> class or interface
515 * <td> <td align=center> L<i>classname</i>;
516 * <tr><td> double <td> <td align=center> D
517 * <tr><td> float <td> <td align=center> F
518 * <tr><td> int <td> <td align=center> I
519 * <tr><td> long <td> <td align=center> J
520 * <tr><td> short <td> <td align=center> S
521 * </table></blockquote>
523 * <p> The class or interface name <i>classname</i> is the binary name of
524 * the class specified above.
528 * String.class.getName()
529 * returns "java.lang.String"
530 * byte.class.getName()
532 * (new Object[3]).getClass().getName()
533 * returns "[Ljava.lang.Object;"
534 * (new int[3][4][5][6][7][8][9]).getClass().getName()
536 * </pre></blockquote>
538 * @return the name of the class or interface
539 * represented by this object.
541 public String getName() {
542 return jvmName().replace('/', '.');
545 @JavaScriptBody(args = {}, body = "return this.jvmName;")
546 private native String jvmName();
550 * Returns an array of {@code TypeVariable} objects that represent the
551 * type variables declared by the generic declaration represented by this
552 * {@code GenericDeclaration} object, in declaration order. Returns an
553 * array of length 0 if the underlying generic declaration declares no type
556 * @return an array of {@code TypeVariable} objects that represent
557 * the type variables declared by this generic declaration
558 * @throws java.lang.reflect.GenericSignatureFormatError if the generic
559 * signature of this generic declaration does not conform to
560 * the format specified in
561 * <cite>The Java™ Virtual Machine Specification</cite>
564 public TypeVariable<Class<T>>[] getTypeParameters() {
565 throw new UnsupportedOperationException();
569 * Returns the {@code Class} representing the superclass of the entity
570 * (class, interface, primitive type or void) represented by this
571 * {@code Class}. If this {@code Class} represents either the
572 * {@code Object} class, an interface, a primitive type, or void, then
573 * null is returned. If this object represents an array class then the
574 * {@code Class} object representing the {@code Object} class is
577 * @return the superclass of the class represented by this object.
579 @JavaScriptBody(args = {}, body = "return this.superclass;")
580 public native Class<? super T> getSuperclass();
583 * Returns the Java language modifiers for this class or interface, encoded
584 * in an integer. The modifiers consist of the Java Virtual Machine's
585 * constants for {@code public}, {@code protected},
586 * {@code private}, {@code final}, {@code static},
587 * {@code abstract} and {@code interface}; they should be decoded
588 * using the methods of class {@code Modifier}.
590 * <p> If the underlying class is an array class, then its
591 * {@code public}, {@code private} and {@code protected}
592 * modifiers are the same as those of its component type. If this
593 * {@code Class} represents a primitive type or void, its
594 * {@code public} modifier is always {@code true}, and its
595 * {@code protected} and {@code private} modifiers are always
596 * {@code false}. If this object represents an array class, a
597 * primitive type or void, then its {@code final} modifier is always
598 * {@code true} and its interface modifier is always
599 * {@code false}. The values of its other modifiers are not determined
600 * by this specification.
602 * <p> The modifier encodings are defined in <em>The Java Virtual Machine
603 * Specification</em>, table 4.1.
605 * @return the {@code int} representing the modifiers for this class
606 * @see java.lang.reflect.Modifier
609 public int getModifiers() {
615 * Returns the simple name of the underlying class as given in the
616 * source code. Returns an empty string if the underlying class is
619 * <p>The simple name of an array is the simple name of the
620 * component type with "[]" appended. In particular the simple
621 * name of an array whose component type is anonymous is "[]".
623 * @return the simple name of the underlying class
626 public String getSimpleName() {
628 return getComponentType().getSimpleName()+"[]";
630 String simpleName = getSimpleBinaryName();
631 if (simpleName == null) { // top level class
632 simpleName = getName();
633 return simpleName.substring(simpleName.lastIndexOf(".")+1); // strip the package name
635 // According to JLS3 "Binary Compatibility" (13.1) the binary
636 // name of non-package classes (not top level) is the binary
637 // name of the immediately enclosing class followed by a '$' followed by:
638 // (for nested and inner classes): the simple name.
639 // (for local classes): 1 or more digits followed by the simple name.
640 // (for anonymous classes): 1 or more digits.
642 // Since getSimpleBinaryName() will strip the binary name of
643 // the immediatly enclosing class, we are now looking at a
644 // string that matches the regular expression "\$[0-9]*"
645 // followed by a simple name (considering the simple of an
646 // anonymous class to be the empty string).
648 // Remove leading "\$[0-9]*" from the name
649 int length = simpleName.length();
650 if (length < 1 || simpleName.charAt(0) != '$')
651 throw new IllegalStateException("Malformed class name");
653 while (index < length && isAsciiDigit(simpleName.charAt(index)))
655 // Eventually, this is the empty string iff this is an anonymous class
656 return simpleName.substring(index);
660 * Returns the "simple binary name" of the underlying class, i.e.,
661 * the binary name without the leading enclosing class name.
662 * Returns {@code null} if the underlying class is a top level
665 private String getSimpleBinaryName() {
666 Class<?> enclosingClass = null; // XXX getEnclosingClass();
667 if (enclosingClass == null) // top level class
669 // Otherwise, strip the enclosing class' name
671 return getName().substring(enclosingClass.getName().length());
672 } catch (IndexOutOfBoundsException ex) {
673 throw new IllegalStateException("Malformed class name");
678 * Returns an array containing {@code Field} objects reflecting all
679 * the accessible public fields of the class or interface represented by
680 * this {@code Class} object. The elements in the array returned are
681 * not sorted and are not in any particular order. This method returns an
682 * array of length 0 if the class or interface has no accessible public
683 * fields, or if it represents an array class, a primitive type, or void.
685 * <p> Specifically, if this {@code Class} object represents a class,
686 * this method returns the public fields of this class and of all its
687 * superclasses. If this {@code Class} object represents an
688 * interface, this method returns the fields of this interface and of all
689 * its superinterfaces.
691 * <p> The implicit length field for array class is not reflected by this
692 * method. User code should use the methods of class {@code Array} to
695 * <p> See <em>The Java Language Specification</em>, sections 8.2 and 8.3.
697 * @return the array of {@code Field} objects representing the
699 * @exception SecurityException
700 * If a security manager, <i>s</i>, is present and any of the
701 * following conditions is met:
706 * {@link SecurityManager#checkMemberAccess
707 * s.checkMemberAccess(this, Member.PUBLIC)} denies
708 * access to the fields within this class
710 * <li> the caller's class loader is not the same as or an
711 * ancestor of the class loader for the current class and
712 * invocation of {@link SecurityManager#checkPackageAccess
713 * s.checkPackageAccess()} denies access to the package
720 public Field[] getFields() throws SecurityException {
721 throw new SecurityException();
725 * Returns an array containing {@code Method} objects reflecting all
726 * the public <em>member</em> methods of the class or interface represented
727 * by this {@code Class} object, including those declared by the class
728 * or interface and those inherited from superclasses and
729 * superinterfaces. Array classes return all the (public) member methods
730 * inherited from the {@code Object} class. The elements in the array
731 * returned are not sorted and are not in any particular order. This
732 * method returns an array of length 0 if this {@code Class} object
733 * represents a class or interface that has no public member methods, or if
734 * this {@code Class} object represents a primitive type or void.
736 * <p> The class initialization method {@code <clinit>} is not
737 * included in the returned array. If the class declares multiple public
738 * member methods with the same parameter types, they are all included in
739 * the returned array.
741 * <p> See <em>The Java Language Specification</em>, sections 8.2 and 8.4.
743 * @return the array of {@code Method} objects representing the
744 * public methods of this class
745 * @exception SecurityException
746 * If a security manager, <i>s</i>, is present and any of the
747 * following conditions is met:
752 * {@link SecurityManager#checkMemberAccess
753 * s.checkMemberAccess(this, Member.PUBLIC)} denies
754 * access to the methods within this class
756 * <li> the caller's class loader is not the same as or an
757 * ancestor of the class loader for the current class and
758 * invocation of {@link SecurityManager#checkPackageAccess
759 * s.checkPackageAccess()} denies access to the package
766 public Method[] getMethods() throws SecurityException {
767 return MethodImpl.findMethods(this, 0x01);
771 * Returns a {@code Field} object that reflects the specified public
772 * member field of the class or interface represented by this
773 * {@code Class} object. The {@code name} parameter is a
774 * {@code String} specifying the simple name of the desired field.
776 * <p> The field to be reflected is determined by the algorithm that
777 * follows. Let C be the class represented by this object:
779 * <LI> If C declares a public field with the name specified, that is the
780 * field to be reflected.</LI>
781 * <LI> If no field was found in step 1 above, this algorithm is applied
782 * recursively to each direct superinterface of C. The direct
783 * superinterfaces are searched in the order they were declared.</LI>
784 * <LI> If no field was found in steps 1 and 2 above, and C has a
785 * superclass S, then this algorithm is invoked recursively upon S.
786 * If C has no superclass, then a {@code NoSuchFieldException}
790 * <p> See <em>The Java Language Specification</em>, sections 8.2 and 8.3.
792 * @param name the field name
793 * @return the {@code Field} object of this class specified by
795 * @exception NoSuchFieldException if a field with the specified name is
797 * @exception NullPointerException if {@code name} is {@code null}
798 * @exception SecurityException
799 * If a security manager, <i>s</i>, is present and any of the
800 * following conditions is met:
805 * {@link SecurityManager#checkMemberAccess
806 * s.checkMemberAccess(this, Member.PUBLIC)} denies
807 * access to the field
809 * <li> the caller's class loader is not the same as or an
810 * ancestor of the class loader for the current class and
811 * invocation of {@link SecurityManager#checkPackageAccess
812 * s.checkPackageAccess()} denies access to the package
819 public Field getField(String name)
820 throws SecurityException {
821 throw new SecurityException();
826 * Returns a {@code Method} object that reflects the specified public
827 * member method of the class or interface represented by this
828 * {@code Class} object. The {@code name} parameter is a
829 * {@code String} specifying the simple name of the desired method. The
830 * {@code parameterTypes} parameter is an array of {@code Class}
831 * objects that identify the method's formal parameter types, in declared
832 * order. If {@code parameterTypes} is {@code null}, it is
833 * treated as if it were an empty array.
835 * <p> If the {@code name} is "{@code <init>};"or "{@code <clinit>}" a
836 * {@code NoSuchMethodException} is raised. Otherwise, the method to
837 * be reflected is determined by the algorithm that follows. Let C be the
838 * class represented by this object:
840 * <LI> C is searched for any <I>matching methods</I>. If no matching
841 * method is found, the algorithm of step 1 is invoked recursively on
842 * the superclass of C.</LI>
843 * <LI> If no method was found in step 1 above, the superinterfaces of C
844 * are searched for a matching method. If any such method is found, it
848 * To find a matching method in a class C: If C declares exactly one
849 * public method with the specified name and exactly the same formal
850 * parameter types, that is the method reflected. If more than one such
851 * method is found in C, and one of these methods has a return type that is
852 * more specific than any of the others, that method is reflected;
853 * otherwise one of the methods is chosen arbitrarily.
855 * <p>Note that there may be more than one matching method in a
856 * class because while the Java language forbids a class to
857 * declare multiple methods with the same signature but different
858 * return types, the Java virtual machine does not. This
859 * increased flexibility in the virtual machine can be used to
860 * implement various language features. For example, covariant
861 * returns can be implemented with {@linkplain
862 * java.lang.reflect.Method#isBridge bridge methods}; the bridge
863 * method and the method being overridden would have the same
864 * signature but different return types.
866 * <p> See <em>The Java Language Specification</em>, sections 8.2 and 8.4.
868 * @param name the name of the method
869 * @param parameterTypes the list of parameters
870 * @return the {@code Method} object that matches the specified
871 * {@code name} and {@code parameterTypes}
872 * @exception NoSuchMethodException if a matching method is not found
873 * or if the name is "<init>"or "<clinit>".
874 * @exception NullPointerException if {@code name} is {@code null}
875 * @exception SecurityException
876 * If a security manager, <i>s</i>, is present and any of the
877 * following conditions is met:
882 * {@link SecurityManager#checkMemberAccess
883 * s.checkMemberAccess(this, Member.PUBLIC)} denies
884 * access to the method
886 * <li> the caller's class loader is not the same as or an
887 * ancestor of the class loader for the current class and
888 * invocation of {@link SecurityManager#checkPackageAccess
889 * s.checkPackageAccess()} denies access to the package
896 public Method getMethod(String name, Class<?>... parameterTypes)
897 throws SecurityException, NoSuchMethodException {
898 Method m = MethodImpl.findMethod(this, name, parameterTypes);
900 StringBuilder sb = new StringBuilder();
901 sb.append(getName()).append('.').append(name).append('(');
903 for (int i = 0; i < parameterTypes.length; i++) {
904 sb.append(sep).append(parameterTypes[i].getName());
908 throw new NoSuchMethodException(sb.toString());
914 * Character.isDigit answers {@code true} to some non-ascii
915 * digits. This one does not.
917 private static boolean isAsciiDigit(char c) {
918 return '0' <= c && c <= '9';
922 * Returns the canonical name of the underlying class as
923 * defined by the Java Language Specification. Returns null if
924 * the underlying class does not have a canonical name (i.e., if
925 * it is a local or anonymous class or an array whose component
926 * type does not have a canonical name).
927 * @return the canonical name of the underlying class if it exists, and
928 * {@code null} otherwise.
931 public String getCanonicalName() {
933 String canonicalName = getComponentType().getCanonicalName();
934 if (canonicalName != null)
935 return canonicalName + "[]";
939 // if (isLocalOrAnonymousClass())
941 // Class<?> enclosingClass = getEnclosingClass();
942 Class<?> enclosingClass = null;
943 if (enclosingClass == null) { // top level class
946 String enclosingName = enclosingClass.getCanonicalName();
947 if (enclosingName == null)
949 return enclosingName + "." + getSimpleName();
954 * Finds a resource with a given name. The rules for searching resources
955 * associated with a given class are implemented by the defining
956 * {@linkplain ClassLoader class loader} of the class. This method
957 * delegates to this object's class loader. If this object was loaded by
958 * the bootstrap class loader, the method delegates to {@link
959 * ClassLoader#getSystemResourceAsStream}.
961 * <p> Before delegation, an absolute resource name is constructed from the
962 * given resource name using this algorithm:
966 * <li> If the {@code name} begins with a {@code '/'}
967 * (<tt>'\u002f'</tt>), then the absolute name of the resource is the
968 * portion of the {@code name} following the {@code '/'}.
970 * <li> Otherwise, the absolute name is of the following form:
973 * {@code modified_package_name/name}
976 * <p> Where the {@code modified_package_name} is the package name of this
977 * object with {@code '/'} substituted for {@code '.'}
978 * (<tt>'\u002e'</tt>).
982 * @param name name of the desired resource
983 * @return A {@link java.io.InputStream} object or {@code null} if
984 * no resource with this name is found
985 * @throws NullPointerException If {@code name} is {@code null}
988 public InputStream getResourceAsStream(String name) {
989 name = resolveName(name);
990 byte[] arr = getResourceAsStream0(name);
991 return arr == null ? null : new ByteArrayInputStream(arr);
994 @JavaScriptBody(args = "name", body =
995 "return (vm.loadBytes) ? vm.loadBytes(name) : null;"
997 private static native byte[] getResourceAsStream0(String name);
1000 * Finds a resource with a given name. The rules for searching resources
1001 * associated with a given class are implemented by the defining
1002 * {@linkplain ClassLoader class loader} of the class. This method
1003 * delegates to this object's class loader. If this object was loaded by
1004 * the bootstrap class loader, the method delegates to {@link
1005 * ClassLoader#getSystemResource}.
1007 * <p> Before delegation, an absolute resource name is constructed from the
1008 * given resource name using this algorithm:
1012 * <li> If the {@code name} begins with a {@code '/'}
1013 * (<tt>'\u002f'</tt>), then the absolute name of the resource is the
1014 * portion of the {@code name} following the {@code '/'}.
1016 * <li> Otherwise, the absolute name is of the following form:
1019 * {@code modified_package_name/name}
1022 * <p> Where the {@code modified_package_name} is the package name of this
1023 * object with {@code '/'} substituted for {@code '.'}
1024 * (<tt>'\u002e'</tt>).
1028 * @param name name of the desired resource
1029 * @return A {@link java.net.URL} object or {@code null} if no
1030 * resource with this name is found
1033 public java.net.URL getResource(String name) {
1034 InputStream is = getResourceAsStream(name);
1035 return is == null ? null : newResourceURL(URL.class, "res:/" + name, is);
1038 @JavaScriptBody(args = { "url", "spec", "is" }, body =
1039 "var u = url.cnstr(true);\n"
1040 + "u.constructor.cons__VLjava_lang_String_2Ljava_io_InputStream_2.call(u, spec, is);\n"
1043 private static native URL newResourceURL(Class<URL> url, String spec, InputStream is);
1046 * Add a package name prefix if the name is not absolute Remove leading "/"
1047 * if name is absolute
1049 private String resolveName(String name) {
1053 if (!name.startsWith("/")) {
1055 while (c.isArray()) {
1056 c = c.getComponentType();
1058 String baseName = c.getName();
1059 int index = baseName.lastIndexOf('.');
1061 name = baseName.substring(0, index).replace('.', '/')
1065 name = name.substring(1);
1071 * Returns the class loader for the class. Some implementations may use
1072 * null to represent the bootstrap class loader. This method will return
1073 * null in such implementations if this class was loaded by the bootstrap
1076 * <p> If a security manager is present, and the caller's class loader is
1077 * not null and the caller's class loader is not the same as or an ancestor of
1078 * the class loader for the class whose class loader is requested, then
1079 * this method calls the security manager's {@code checkPermission}
1080 * method with a {@code RuntimePermission("getClassLoader")}
1081 * permission to ensure it's ok to access the class loader for the class.
1084 * represents a primitive type or void, null is returned.
1086 * @return the class loader that loaded the class or interface
1087 * represented by this object.
1088 * @throws SecurityException
1089 * if a security manager exists and its
1090 * {@code checkPermission} method denies
1091 * access to the class loader for the class.
1092 * @see java.lang.ClassLoader
1093 * @see SecurityManager#checkPermission
1094 * @see java.lang.RuntimePermission
1096 public ClassLoader getClassLoader() {
1097 throw new SecurityException();
1101 * Returns the {@code Class} representing the component type of an
1102 * array. If this class does not represent an array class this method
1105 * @return the {@code Class} representing the component type of this
1106 * class if this class is an array
1107 * @see java.lang.reflect.Array
1110 public Class<?> getComponentType() {
1113 return getComponentType0();
1114 } catch (ClassNotFoundException cnfe) {
1115 throw new IllegalStateException(cnfe);
1121 private Class<?> getComponentType0() throws ClassNotFoundException {
1122 String n = getName().substring(1);
1123 switch (n.charAt(0)) {
1125 n = n.substring(1, n.length() - 1);
1126 return Class.forName(n);
1128 return Integer.TYPE;
1138 return Boolean.TYPE;
1144 return Character.TYPE;
1146 return defineArray(n);
1148 throw new ClassNotFoundException("Unknown component type of " + getName());
1152 @JavaScriptBody(args = { "sig" }, body =
1153 "var c = Array[sig];\n" +
1154 "if (c) return c;\n" +
1155 "c = vm.java_lang_Class(true);\n" +
1156 "c.jvmName = sig;\n" +
1157 "c.superclass = vm.java_lang_Object(false).$class;\n" +
1158 "c.array = true;\n" +
1159 "Array[sig] = c;\n" +
1162 private static native Class<?> defineArray(String sig);
1165 * Returns true if and only if this class was declared as an enum in the
1168 * @return true if and only if this class was declared as an enum in the
1172 public boolean isEnum() {
1173 // An enum must both directly extend java.lang.Enum and have
1174 // the ENUM bit set; classes for specialized enum constants
1175 // don't do the former.
1176 return (this.getModifiers() & ENUM) != 0 &&
1177 this.getSuperclass() == java.lang.Enum.class;
1181 * Casts an object to the class or interface represented
1182 * by this {@code Class} object.
1184 * @param obj the object to be cast
1185 * @return the object after casting, or null if obj is null
1187 * @throws ClassCastException if the object is not
1188 * null and is not assignable to the type T.
1192 public T cast(Object obj) {
1193 if (obj != null && !isInstance(obj))
1194 throw new ClassCastException(cannotCastMsg(obj));
1198 private String cannotCastMsg(Object obj) {
1199 return "Cannot cast " + obj.getClass().getName() + " to " + getName();
1203 * Casts this {@code Class} object to represent a subclass of the class
1204 * represented by the specified class object. Checks that that the cast
1205 * is valid, and throws a {@code ClassCastException} if it is not. If
1206 * this method succeeds, it always returns a reference to this class object.
1208 * <p>This method is useful when a client needs to "narrow" the type of
1209 * a {@code Class} object to pass it to an API that restricts the
1210 * {@code Class} objects that it is willing to accept. A cast would
1211 * generate a compile-time warning, as the correctness of the cast
1212 * could not be checked at runtime (because generic types are implemented
1215 * @return this {@code Class} object, cast to represent a subclass of
1216 * the specified class object.
1217 * @throws ClassCastException if this {@code Class} object does not
1218 * represent a subclass of the specified class (here "subclass" includes
1219 * the class itself).
1222 public <U> Class<? extends U> asSubclass(Class<U> clazz) {
1223 if (clazz.isAssignableFrom(this))
1224 return (Class<? extends U>) this;
1226 throw new ClassCastException(this.toString());
1229 @JavaScriptBody(args = { "ac" },
1232 + " return this.anno['L' + ac.jvmName + ';'];"
1233 + "} else return null;"
1235 private Object getAnnotationData(Class<?> annotationClass) {
1236 throw new UnsupportedOperationException();
1239 * @throws NullPointerException {@inheritDoc}
1242 public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {
1243 Object data = getAnnotationData(annotationClass);
1244 return data == null ? null : AnnotationImpl.create(annotationClass, data);
1248 * @throws NullPointerException {@inheritDoc}
1251 @JavaScriptBody(args = { "ac" },
1252 body = "if (this.anno && this.anno['L' + ac.jvmName + ';']) { return true; }"
1253 + "else return false;"
1255 public boolean isAnnotationPresent(
1256 Class<? extends Annotation> annotationClass) {
1257 if (annotationClass == null)
1258 throw new NullPointerException();
1260 return getAnnotation(annotationClass) != null;
1263 @JavaScriptBody(args = {}, body = "return this.anno;")
1264 private Object getAnnotationData() {
1265 throw new UnsupportedOperationException();
1271 public Annotation[] getAnnotations() {
1272 Object data = getAnnotationData();
1273 return data == null ? new Annotation[0] : AnnotationImpl.create(data);
1279 public Annotation[] getDeclaredAnnotations() {
1280 throw new UnsupportedOperationException();
1283 @JavaScriptBody(args = "type", body = ""
1284 + "var c = vm.java_lang_Class(true);"
1285 + "c.jvmName = type;"
1286 + "c.primitive = true;"
1289 native static Class getPrimitiveClass(String type);
1291 @JavaScriptBody(args = {}, body =
1292 "return vm.desiredAssertionStatus ? vm.desiredAssertionStatus : false;"
1294 public native boolean desiredAssertionStatus();