emul/mini/src/main/java/java/lang/Class.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Sat, 26 Jan 2013 08:47:05 +0100
changeset 592 5e13b1ac2886
parent 576 b679a7dad297
parent 586 b670af2aa0f7
child 604 3fcc279c921b
child 658 578cea5b4359
permissions -rw-r--r--
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.
     1 /*
     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.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    25 
    26 package java.lang;
    27 
    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;
    35 import java.net.URL;
    36 import org.apidesign.bck2brwsr.core.JavaScriptBody;
    37 import org.apidesign.bck2brwsr.emul.reflect.MethodImpl;
    38 
    39 /**
    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.
    50  *
    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
    54  * loader.
    55  *
    56  * <p> The following example uses a {@code Class} object to print the
    57  * class name of an object:
    58  *
    59  * <p> <blockquote><pre>
    60  *     void printClassName(Object obj) {
    61  *         System.out.println("The class of " + obj +
    62  *                            " is " + obj.getClass().getName());
    63  *     }
    64  * </pre></blockquote>
    65  *
    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&trade; Language Specification</cite>.
    69  * For example:
    70  *
    71  * <p> <blockquote>
    72  *     {@code System.out.println("The name of class Foo is: "+Foo.class.getName());}
    73  * </blockquote>
    74  *
    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
    78  * unknown.
    79  *
    80  * @author  unascribed
    81  * @see     java.lang.ClassLoader#defineClass(byte[], int, int)
    82  * @since   JDK1.0
    83  */
    84 public final
    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;
    92 
    93     /*
    94      * Constructor. Only the Java Virtual Machine creates Class
    95      * objects.
    96      */
    97     private Class() {}
    98 
    99 
   100     /**
   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
   107      * "void".
   108      *
   109      * @return a string representation of this class object.
   110      */
   111     public String toString() {
   112         return (isInterface() ? "interface " : (isPrimitive() ? "" : "class "))
   113             + getName();
   114     }
   115 
   116 
   117     /**
   118      * Returns the {@code Class} object associated with the class or
   119      * interface with the given string name.  Invoking this method is
   120      * equivalent to:
   121      *
   122      * <blockquote>
   123      *  {@code Class.forName(className, true, currentLoader)}
   124      * </blockquote>
   125      *
   126      * where {@code currentLoader} denotes the defining class loader of
   127      * the current class.
   128      *
   129      * <p> For example, the following code fragment returns the
   130      * runtime {@code Class} descriptor for the class named
   131      * {@code java.lang.Thread}:
   132      *
   133      * <blockquote>
   134      *   {@code Class t = Class.forName("java.lang.Thread")}
   135      * </blockquote>
   136      * <p>
   137      * A call to {@code forName("X")} causes the class named
   138      * {@code X} to be initialized.
   139      *
   140      * @param      className   the fully qualified name of the desired class.
   141      * @return     the {@code Class} object for the class with the
   142      *             specified name.
   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
   147      */
   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
   155             }
   156             return arrType;
   157         }
   158         Class<?> c = loadCls(className, className.replace('.', '_'));
   159         if (c == null) {
   160             throw new ClassNotFoundException(className);
   161         }
   162         return c;
   163     }
   164 
   165 
   166     /**
   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.
   177      *
   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
   182      * types or void.
   183      *
   184      * <p> If {@code name} denotes an array class, the component type of
   185      * the array class is loaded but not initialized.
   186      *
   187      * <p> For example, in an instance method the expression:
   188      *
   189      * <blockquote>
   190      *  {@code Class.forName("Foo")}
   191      * </blockquote>
   192      *
   193      * is equivalent to:
   194      *
   195      * <blockquote>
   196      *  {@code Class.forName("Foo", true, this.getClass().getClassLoader())}
   197      * </blockquote>
   198      *
   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.
   204      *
   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.
   210      *
   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
   215      *
   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
   221      *
   222      * @see       java.lang.Class#forName(String)
   223      * @see       java.lang.ClassLoader
   224      * @since     1.2
   225      */
   226     public static Class<?> forName(String name, boolean initialize,
   227                                    ClassLoader loader)
   228         throws ClassNotFoundException
   229     {
   230         return forName(name);
   231     }
   232     
   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"
   238       + "}\n"
   239       + "return null;"
   240     )
   241     private static native Class<?> loadCls(String n, String c);
   242 
   243 
   244     /**
   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.
   249      *
   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.
   254      * The {@link
   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}.
   259      *
   260      * @return     a newly allocated instance of the class represented by this
   261      *             object.
   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:
   274      *
   275      *             <ul>
   276      *
   277      *             <li> invocation of
   278      *             {@link SecurityManager#checkMemberAccess
   279      *             s.checkMemberAccess(this, Member.PUBLIC)} denies
   280      *             creation of new instances of this class
   281      *
   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
   286      *             of this class
   287      *
   288      *             </ul>
   289      *
   290      */
   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);"
   297         + "\n    return inst;"
   298         + "\n  }"
   299         + "\n  return illegal;"
   300         + "\n}"
   301         + "\nreturn null;"
   302     )
   303     private static native Object newInstance0(Class<?> self, Object illegal);
   304     
   305     public T newInstance()
   306         throws InstantiationException, IllegalAccessException
   307     {
   308         Object illegal = new Object();
   309         Object inst = newInstance0(this, illegal);
   310         if (inst == null) {
   311             throw new InstantiationException(getName());
   312         }
   313         if (inst == illegal) {
   314             throw new IllegalAccessException();
   315         }
   316         return (T)inst;
   317     }
   318 
   319     /**
   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}
   327      * otherwise.
   328      *
   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}.
   343      *
   344      * @param   obj the object to check
   345      * @return  true if {@code obj} is an instance of this class
   346      *
   347      * @since JDK1.1
   348      */
   349     public boolean isInstance(Object obj) {
   350         if (isArray()) {
   351             return isAssignableFrom(obj.getClass());
   352         }
   353         
   354         String prop = "$instOf_" + getName().replace('.', '_');
   355         return hasProperty(obj, prop);
   356     }
   357     
   358     @JavaScriptBody(args = { "who", "prop" }, body = 
   359         "if (who[prop]) return true; else return false;"
   360     )
   361     private static native boolean hasProperty(Object who, String prop);
   362 
   363 
   364     /**
   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
   373      * {@code false}.
   374      *
   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.
   380      *
   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
   385      *            null.
   386      * @since JDK1.1
   387      */
   388     public boolean isAssignableFrom(Class<?> cls) {
   389         if (this == cls) {
   390             return true;
   391         }
   392         
   393         if (isArray()) {
   394             final Class<?> cmpType = cls.getComponentType();
   395             if (isPrimitive()) {
   396                 return this == cmpType;
   397             }
   398             return cmpType != null && getComponentType().isAssignableFrom(cmpType);
   399         }
   400         String prop = "$instOf_" + getName().replace('.', '_');
   401         return hasProperty(cls, prop);
   402     }
   403 
   404 
   405     /**
   406      * Determines if the specified {@code Class} object represents an
   407      * interface type.
   408      *
   409      * @return  {@code true} if this object represents an interface;
   410      *          {@code false} otherwise.
   411      */
   412     public boolean isInterface() {
   413         return (getAccess() & 0x200) != 0;
   414     }
   415     
   416     @JavaScriptBody(args = {}, body = "return this.access;")
   417     private native int getAccess();
   418 
   419 
   420     /**
   421      * Determines if this {@code Class} object represents an array class.
   422      *
   423      * @return  {@code true} if this object represents an array class;
   424      *          {@code false} otherwise.
   425      * @since   JDK1.1
   426      */
   427     public boolean isArray() {
   428         return hasProperty(this, "array"); // NOI18N
   429     }
   430 
   431 
   432     /**
   433      * Determines if the specified {@code Class} object represents a
   434      * primitive type.
   435      *
   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}.
   442      *
   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}.
   446      *
   447      * @return true if and only if this class represents a primitive type
   448      *
   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
   458      * @since JDK1.1
   459      */
   460     @JavaScriptBody(args = {}, body = 
   461            "if (this.primitive) return true;"
   462         + "else return false;"
   463     )
   464     public native boolean isPrimitive();
   465 
   466     /**
   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.
   470      *
   471      * @return {@code true} if this class object represents an annotation
   472      *      type; {@code false} otherwise
   473      * @since 1.5
   474      */
   475     public boolean isAnnotation() {
   476         return (getModifiers() & ANNOTATION) != 0;
   477     }
   478 
   479     /**
   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.
   484      * @since 1.5
   485      */
   486     public boolean isSynthetic() {
   487         return (getModifiers() & SYNTHETIC) != 0;
   488     }
   489 
   490     /**
   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}.
   494      *
   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
   497      * by
   498      * <cite>The Java&trade; Language Specification</cite>.
   499      *
   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.
   503      *
   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:
   508      *
   509      * <blockquote><table summary="Element types and encodings">
   510      * <tr><th> Element Type <th> &nbsp;&nbsp;&nbsp; <th> Encoding
   511      * <tr><td> boolean      <td> &nbsp;&nbsp;&nbsp; <td align=center> Z
   512      * <tr><td> byte         <td> &nbsp;&nbsp;&nbsp; <td align=center> B
   513      * <tr><td> char         <td> &nbsp;&nbsp;&nbsp; <td align=center> C
   514      * <tr><td> class or interface
   515      *                       <td> &nbsp;&nbsp;&nbsp; <td align=center> L<i>classname</i>;
   516      * <tr><td> double       <td> &nbsp;&nbsp;&nbsp; <td align=center> D
   517      * <tr><td> float        <td> &nbsp;&nbsp;&nbsp; <td align=center> F
   518      * <tr><td> int          <td> &nbsp;&nbsp;&nbsp; <td align=center> I
   519      * <tr><td> long         <td> &nbsp;&nbsp;&nbsp; <td align=center> J
   520      * <tr><td> short        <td> &nbsp;&nbsp;&nbsp; <td align=center> S
   521      * </table></blockquote>
   522      *
   523      * <p> The class or interface name <i>classname</i> is the binary name of
   524      * the class specified above.
   525      *
   526      * <p> Examples:
   527      * <blockquote><pre>
   528      * String.class.getName()
   529      *     returns "java.lang.String"
   530      * byte.class.getName()
   531      *     returns "byte"
   532      * (new Object[3]).getClass().getName()
   533      *     returns "[Ljava.lang.Object;"
   534      * (new int[3][4][5][6][7][8][9]).getClass().getName()
   535      *     returns "[[[[[[[I"
   536      * </pre></blockquote>
   537      *
   538      * @return  the name of the class or interface
   539      *          represented by this object.
   540      */
   541     public String getName() {
   542         return jvmName().replace('/', '.');
   543     }
   544 
   545     @JavaScriptBody(args = {}, body = "return this.jvmName;")
   546     private native String jvmName();
   547 
   548     
   549     /**
   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
   554      * variables.
   555      *
   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&trade; Virtual Machine Specification</cite>
   562      * @since 1.5
   563      */
   564     public TypeVariable<Class<T>>[] getTypeParameters() {
   565         throw new UnsupportedOperationException();
   566     }
   567  
   568     /**
   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
   575      * returned.
   576      *
   577      * @return the superclass of the class represented by this object.
   578      */
   579     @JavaScriptBody(args = {}, body = "return this.superclass;")
   580     public native Class<? super T> getSuperclass();
   581 
   582     /**
   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}.
   589      *
   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.
   601      *
   602      * <p> The modifier encodings are defined in <em>The Java Virtual Machine
   603      * Specification</em>, table 4.1.
   604      *
   605      * @return the {@code int} representing the modifiers for this class
   606      * @see     java.lang.reflect.Modifier
   607      * @since JDK1.1
   608      */
   609     public int getModifiers() {
   610         return getAccess();
   611     }
   612 
   613 
   614     /**
   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
   617      * anonymous.
   618      *
   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 "[]".
   622      *
   623      * @return the simple name of the underlying class
   624      * @since 1.5
   625      */
   626     public String getSimpleName() {
   627         if (isArray())
   628             return getComponentType().getSimpleName()+"[]";
   629 
   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
   634         }
   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.
   641 
   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).
   647 
   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");
   652         int index = 1;
   653         while (index < length && isAsciiDigit(simpleName.charAt(index)))
   654             index++;
   655         // Eventually, this is the empty string iff this is an anonymous class
   656         return simpleName.substring(index);
   657     }
   658 
   659     /**
   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
   663      * class.
   664      */
   665     private String getSimpleBinaryName() {
   666         Class<?> enclosingClass = null; // XXX getEnclosingClass();
   667         if (enclosingClass == null) // top level class
   668             return null;
   669         // Otherwise, strip the enclosing class' name
   670         try {
   671             return getName().substring(enclosingClass.getName().length());
   672         } catch (IndexOutOfBoundsException ex) {
   673             throw new IllegalStateException("Malformed class name");
   674         }
   675     }
   676 
   677     /**
   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.
   684      *
   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.
   690      *
   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
   693      * manipulate arrays.
   694      *
   695      * <p> See <em>The Java Language Specification</em>, sections 8.2 and 8.3.
   696      *
   697      * @return the array of {@code Field} objects representing the
   698      * public fields
   699      * @exception  SecurityException
   700      *             If a security manager, <i>s</i>, is present and any of the
   701      *             following conditions is met:
   702      *
   703      *             <ul>
   704      *
   705      *             <li> invocation of
   706      *             {@link SecurityManager#checkMemberAccess
   707      *             s.checkMemberAccess(this, Member.PUBLIC)} denies
   708      *             access to the fields within this class
   709      *
   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
   714      *             of this class
   715      *
   716      *             </ul>
   717      *
   718      * @since JDK1.1
   719      */
   720     public Field[] getFields() throws SecurityException {
   721         throw new SecurityException();
   722     }
   723 
   724     /**
   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.
   735      *
   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.
   740      *
   741      * <p> See <em>The Java Language Specification</em>, sections 8.2 and 8.4.
   742      *
   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:
   748      *
   749      *             <ul>
   750      *
   751      *             <li> invocation of
   752      *             {@link SecurityManager#checkMemberAccess
   753      *             s.checkMemberAccess(this, Member.PUBLIC)} denies
   754      *             access to the methods within this class
   755      *
   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
   760      *             of this class
   761      *
   762      *             </ul>
   763      *
   764      * @since JDK1.1
   765      */
   766     public Method[] getMethods() throws SecurityException {
   767         return MethodImpl.findMethods(this, 0x01);
   768     }
   769 
   770     /**
   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.
   775      *
   776      * <p> The field to be reflected is determined by the algorithm that
   777      * follows.  Let C be the class represented by this object:
   778      * <OL>
   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}
   787      *      is thrown.</LI>
   788      * </OL>
   789      *
   790      * <p> See <em>The Java Language Specification</em>, sections 8.2 and 8.3.
   791      *
   792      * @param name the field name
   793      * @return  the {@code Field} object of this class specified by
   794      * {@code name}
   795      * @exception NoSuchFieldException if a field with the specified name is
   796      *              not found.
   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:
   801      *
   802      *             <ul>
   803      *
   804      *             <li> invocation of
   805      *             {@link SecurityManager#checkMemberAccess
   806      *             s.checkMemberAccess(this, Member.PUBLIC)} denies
   807      *             access to the field
   808      *
   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
   813      *             of this class
   814      *
   815      *             </ul>
   816      *
   817      * @since JDK1.1
   818      */
   819     public Field getField(String name)
   820         throws SecurityException {
   821         throw new SecurityException();
   822     }
   823     
   824     
   825     /**
   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.
   834      *
   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:
   839      * <OL>
   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
   845      *      is reflected.</LI>
   846      * </OL>
   847      *
   848      * To find a matching method in a class C:&nbsp; 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.
   854      *
   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.
   865      *
   866      * <p> See <em>The Java Language Specification</em>, sections 8.2 and 8.4.
   867      *
   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 "&lt;init&gt;"or "&lt;clinit&gt;".
   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:
   878      *
   879      *             <ul>
   880      *
   881      *             <li> invocation of
   882      *             {@link SecurityManager#checkMemberAccess
   883      *             s.checkMemberAccess(this, Member.PUBLIC)} denies
   884      *             access to the method
   885      *
   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
   890      *             of this class
   891      *
   892      *             </ul>
   893      *
   894      * @since JDK1.1
   895      */
   896     public Method getMethod(String name, Class<?>... parameterTypes)
   897         throws SecurityException, NoSuchMethodException {
   898         Method m = MethodImpl.findMethod(this, name, parameterTypes);
   899         if (m == null) {
   900             StringBuilder sb = new StringBuilder();
   901             sb.append(getName()).append('.').append(name).append('(');
   902             String sep = "";
   903             for (int i = 0; i < parameterTypes.length; i++) {
   904                 sb.append(sep).append(parameterTypes[i].getName());
   905                 sep = ", ";
   906             }
   907             sb.append(')');
   908             throw new NoSuchMethodException(sb.toString());
   909         }
   910         return m;
   911     }
   912 
   913     /**
   914      * Character.isDigit answers {@code true} to some non-ascii
   915      * digits.  This one does not.
   916      */
   917     private static boolean isAsciiDigit(char c) {
   918         return '0' <= c && c <= '9';
   919     }
   920 
   921     /**
   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.
   929      * @since 1.5
   930      */
   931     public String getCanonicalName() {
   932         if (isArray()) {
   933             String canonicalName = getComponentType().getCanonicalName();
   934             if (canonicalName != null)
   935                 return canonicalName + "[]";
   936             else
   937                 return null;
   938         }
   939 //        if (isLocalOrAnonymousClass())
   940 //            return null;
   941 //        Class<?> enclosingClass = getEnclosingClass();
   942         Class<?> enclosingClass = null;
   943         if (enclosingClass == null) { // top level class
   944             return getName();
   945         } else {
   946             String enclosingName = enclosingClass.getCanonicalName();
   947             if (enclosingName == null)
   948                 return null;
   949             return enclosingName + "." + getSimpleName();
   950         }
   951     }
   952 
   953     /**
   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}.
   960      *
   961      * <p> Before delegation, an absolute resource name is constructed from the
   962      * given resource name using this algorithm:
   963      *
   964      * <ul>
   965      *
   966      * <li> If the {@code name} begins with a {@code '/'}
   967      * (<tt>'&#92;u002f'</tt>), then the absolute name of the resource is the
   968      * portion of the {@code name} following the {@code '/'}.
   969      *
   970      * <li> Otherwise, the absolute name is of the following form:
   971      *
   972      * <blockquote>
   973      *   {@code modified_package_name/name}
   974      * </blockquote>
   975      *
   976      * <p> Where the {@code modified_package_name} is the package name of this
   977      * object with {@code '/'} substituted for {@code '.'}
   978      * (<tt>'&#92;u002e'</tt>).
   979      *
   980      * </ul>
   981      *
   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}
   986      * @since  JDK1.1
   987      */
   988      public InputStream getResourceAsStream(String name) {
   989         name = resolveName(name);
   990         byte[] arr = getResourceAsStream0(name);
   991         return arr == null ? null : new ByteArrayInputStream(arr);
   992      }
   993      
   994      @JavaScriptBody(args = "name", body = 
   995          "return (vm.loadBytes) ? vm.loadBytes(name) : null;"
   996      )
   997      private static native byte[] getResourceAsStream0(String name);
   998 
   999     /**
  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}.
  1006      *
  1007      * <p> Before delegation, an absolute resource name is constructed from the
  1008      * given resource name using this algorithm:
  1009      *
  1010      * <ul>
  1011      *
  1012      * <li> If the {@code name} begins with a {@code '/'}
  1013      * (<tt>'&#92;u002f'</tt>), then the absolute name of the resource is the
  1014      * portion of the {@code name} following the {@code '/'}.
  1015      *
  1016      * <li> Otherwise, the absolute name is of the following form:
  1017      *
  1018      * <blockquote>
  1019      *   {@code modified_package_name/name}
  1020      * </blockquote>
  1021      *
  1022      * <p> Where the {@code modified_package_name} is the package name of this
  1023      * object with {@code '/'} substituted for {@code '.'}
  1024      * (<tt>'&#92;u002e'</tt>).
  1025      *
  1026      * </ul>
  1027      *
  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
  1031      * @since  JDK1.1
  1032      */
  1033     public java.net.URL getResource(String name) {
  1034         InputStream is = getResourceAsStream(name);
  1035         return is == null ? null : newResourceURL(URL.class, "res:/" + name, is);
  1036     }
  1037     
  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"
  1041       + "return u;"
  1042     )
  1043     private static native URL newResourceURL(Class<URL> url, String spec, InputStream is);
  1044 
  1045    /**
  1046      * Add a package name prefix if the name is not absolute Remove leading "/"
  1047      * if name is absolute
  1048      */
  1049     private String resolveName(String name) {
  1050         if (name == null) {
  1051             return name;
  1052         }
  1053         if (!name.startsWith("/")) {
  1054             Class<?> c = this;
  1055             while (c.isArray()) {
  1056                 c = c.getComponentType();
  1057             }
  1058             String baseName = c.getName();
  1059             int index = baseName.lastIndexOf('.');
  1060             if (index != -1) {
  1061                 name = baseName.substring(0, index).replace('.', '/')
  1062                     +"/"+name;
  1063             }
  1064         } else {
  1065             name = name.substring(1);
  1066         }
  1067         return name;
  1068     }
  1069     
  1070     /**
  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
  1074      * class loader.
  1075      *
  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.
  1082      *
  1083      * <p>If this object
  1084      * represents a primitive type or void, null is returned.
  1085      *
  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
  1095      */
  1096     public ClassLoader getClassLoader() {
  1097         throw new SecurityException();
  1098     }
  1099     
  1100     /**
  1101      * Returns the {@code Class} representing the component type of an
  1102      * array.  If this class does not represent an array class this method
  1103      * returns null.
  1104      *
  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
  1108      * @since JDK1.1
  1109      */
  1110     public Class<?> getComponentType() {
  1111         if (isArray()) {
  1112             try {
  1113                 return getComponentType0();
  1114             } catch (ClassNotFoundException cnfe) {
  1115                 throw new IllegalStateException(cnfe);
  1116             }
  1117         }
  1118         return null;
  1119     }
  1120 
  1121     private Class<?> getComponentType0() throws ClassNotFoundException {
  1122         String n = getName().substring(1);
  1123         switch (n.charAt(0)) {
  1124             case 'L': 
  1125                 n = n.substring(1, n.length() - 1);
  1126                 return Class.forName(n);
  1127             case 'I':
  1128                 return Integer.TYPE;
  1129             case 'J':
  1130                 return Long.TYPE;
  1131             case 'D':
  1132                 return Double.TYPE;
  1133             case 'F':
  1134                 return Float.TYPE;
  1135             case 'B':
  1136                 return Byte.TYPE;
  1137             case 'Z':
  1138                 return Boolean.TYPE;
  1139             case 'S':
  1140                 return Short.TYPE;
  1141             case 'V':
  1142                 return Void.TYPE;
  1143             case 'C':
  1144                 return Character.TYPE;
  1145             case '[':
  1146                 return defineArray(n);
  1147             default:
  1148                 throw new ClassNotFoundException("Unknown component type of " + getName());
  1149         }
  1150     }
  1151     
  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" +
  1160         "return c;"
  1161     )
  1162     private static native Class<?> defineArray(String sig);
  1163     
  1164     /**
  1165      * Returns true if and only if this class was declared as an enum in the
  1166      * source code.
  1167      *
  1168      * @return true if and only if this class was declared as an enum in the
  1169      *     source code
  1170      * @since 1.5
  1171      */
  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;
  1178     }
  1179 
  1180     /**
  1181      * Casts an object to the class or interface represented
  1182      * by this {@code Class} object.
  1183      *
  1184      * @param obj the object to be cast
  1185      * @return the object after casting, or null if obj is null
  1186      *
  1187      * @throws ClassCastException if the object is not
  1188      * null and is not assignable to the type T.
  1189      *
  1190      * @since 1.5
  1191      */
  1192     public T cast(Object obj) {
  1193         if (obj != null && !isInstance(obj))
  1194             throw new ClassCastException(cannotCastMsg(obj));
  1195         return (T) obj;
  1196     }
  1197 
  1198     private String cannotCastMsg(Object obj) {
  1199         return "Cannot cast " + obj.getClass().getName() + " to " + getName();
  1200     }
  1201 
  1202     /**
  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.
  1207      *
  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
  1213      * by erasure).
  1214      *
  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).
  1220      * @since 1.5
  1221      */
  1222     public <U> Class<? extends U> asSubclass(Class<U> clazz) {
  1223         if (clazz.isAssignableFrom(this))
  1224             return (Class<? extends U>) this;
  1225         else
  1226             throw new ClassCastException(this.toString());
  1227     }
  1228 
  1229     @JavaScriptBody(args = { "ac" }, 
  1230         body = 
  1231           "if (this.anno) {"
  1232         + "  return this.anno['L' + ac.jvmName + ';'];"
  1233         + "} else return null;"
  1234     )
  1235     private Object getAnnotationData(Class<?> annotationClass) {
  1236         throw new UnsupportedOperationException();
  1237     }
  1238     /**
  1239      * @throws NullPointerException {@inheritDoc}
  1240      * @since 1.5
  1241      */
  1242     public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {
  1243         Object data = getAnnotationData(annotationClass);
  1244         return data == null ? null : AnnotationImpl.create(annotationClass, data);
  1245     }
  1246 
  1247     /**
  1248      * @throws NullPointerException {@inheritDoc}
  1249      * @since 1.5
  1250      */
  1251     @JavaScriptBody(args = { "ac" }, 
  1252         body = "if (this.anno && this.anno['L' + ac.jvmName + ';']) { return true; }"
  1253         + "else return false;"
  1254     )
  1255     public boolean isAnnotationPresent(
  1256         Class<? extends Annotation> annotationClass) {
  1257         if (annotationClass == null)
  1258             throw new NullPointerException();
  1259 
  1260         return getAnnotation(annotationClass) != null;
  1261     }
  1262 
  1263     @JavaScriptBody(args = {}, body = "return this.anno;")
  1264     private Object getAnnotationData() {
  1265         throw new UnsupportedOperationException();
  1266     }
  1267 
  1268     /**
  1269      * @since 1.5
  1270      */
  1271     public Annotation[] getAnnotations() {
  1272         Object data = getAnnotationData();
  1273         return data == null ? new Annotation[0] : AnnotationImpl.create(data);
  1274     }
  1275 
  1276     /**
  1277      * @since 1.5
  1278      */
  1279     public Annotation[] getDeclaredAnnotations()  {
  1280         throw new UnsupportedOperationException();
  1281     }
  1282 
  1283     @JavaScriptBody(args = "type", body = ""
  1284         + "var c = vm.java_lang_Class(true);"
  1285         + "c.jvmName = type;"
  1286         + "c.primitive = true;"
  1287         + "return c;"
  1288     )
  1289     native static Class getPrimitiveClass(String type);
  1290 
  1291     @JavaScriptBody(args = {}, body = 
  1292         "return vm.desiredAssertionStatus ? vm.desiredAssertionStatus : false;"
  1293     )
  1294     public native boolean desiredAssertionStatus();
  1295 }