emul/src/main/java/java/lang/Class.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Mon, 14 Jan 2013 11:30:56 +0100
branchUseFunctionCall
changeset 443 9359b006782b
parent 442 b107ed66f2e7
child 448 ac05de5a8786
permissions -rw-r--r--
Using 'this' in @JavaScriptBody instance methods
jaroslav@56
     1
/*
jaroslav@56
     2
 * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
jaroslav@56
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
jaroslav@56
     4
 *
jaroslav@56
     5
 * This code is free software; you can redistribute it and/or modify it
jaroslav@56
     6
 * under the terms of the GNU General Public License version 2 only, as
jaroslav@56
     7
 * published by the Free Software Foundation.  Oracle designates this
jaroslav@56
     8
 * particular file as subject to the "Classpath" exception as provided
jaroslav@56
     9
 * by Oracle in the LICENSE file that accompanied this code.
jaroslav@56
    10
 *
jaroslav@56
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
jaroslav@56
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
jaroslav@56
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
jaroslav@56
    14
 * version 2 for more details (a copy is included in the LICENSE file that
jaroslav@56
    15
 * accompanied this code).
jaroslav@56
    16
 *
jaroslav@56
    17
 * You should have received a copy of the GNU General Public License version
jaroslav@56
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
jaroslav@56
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
jaroslav@56
    20
 *
jaroslav@56
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
jaroslav@56
    22
 * or visit www.oracle.com if you need additional information or have any
jaroslav@56
    23
 * questions.
jaroslav@56
    24
 */
jaroslav@56
    25
jaroslav@56
    26
package java.lang;
jaroslav@56
    27
jaroslav@424
    28
import java.io.ByteArrayInputStream;
jaroslav@266
    29
import org.apidesign.bck2brwsr.emul.AnnotationImpl;
jaroslav@122
    30
import java.io.InputStream;
jaroslav@56
    31
import java.lang.annotation.Annotation;
jaroslav@261
    32
import java.lang.reflect.Field;
jaroslav@261
    33
import java.lang.reflect.Method;
jaroslav@260
    34
import java.lang.reflect.TypeVariable;
jaroslav@225
    35
import org.apidesign.bck2brwsr.core.JavaScriptBody;
jaroslav@391
    36
import org.apidesign.bck2brwsr.emul.MethodImpl;
jaroslav@56
    37
jaroslav@56
    38
/**
jaroslav@56
    39
 * Instances of the class {@code Class} represent classes and
jaroslav@56
    40
 * interfaces in a running Java application.  An enum is a kind of
jaroslav@56
    41
 * class and an annotation is a kind of interface.  Every array also
jaroslav@56
    42
 * belongs to a class that is reflected as a {@code Class} object
jaroslav@56
    43
 * that is shared by all arrays with the same element type and number
jaroslav@56
    44
 * of dimensions.  The primitive Java types ({@code boolean},
jaroslav@56
    45
 * {@code byte}, {@code char}, {@code short},
jaroslav@56
    46
 * {@code int}, {@code long}, {@code float}, and
jaroslav@56
    47
 * {@code double}), and the keyword {@code void} are also
jaroslav@56
    48
 * represented as {@code Class} objects.
jaroslav@56
    49
 *
jaroslav@56
    50
 * <p> {@code Class} has no public constructor. Instead {@code Class}
jaroslav@56
    51
 * objects are constructed automatically by the Java Virtual Machine as classes
jaroslav@56
    52
 * are loaded and by calls to the {@code defineClass} method in the class
jaroslav@56
    53
 * loader.
jaroslav@56
    54
 *
jaroslav@56
    55
 * <p> The following example uses a {@code Class} object to print the
jaroslav@56
    56
 * class name of an object:
jaroslav@56
    57
 *
jaroslav@56
    58
 * <p> <blockquote><pre>
jaroslav@56
    59
 *     void printClassName(Object obj) {
jaroslav@56
    60
 *         System.out.println("The class of " + obj +
jaroslav@56
    61
 *                            " is " + obj.getClass().getName());
jaroslav@56
    62
 *     }
jaroslav@56
    63
 * </pre></blockquote>
jaroslav@56
    64
 *
jaroslav@56
    65
 * <p> It is also possible to get the {@code Class} object for a named
jaroslav@56
    66
 * type (or for void) using a class literal.  See Section 15.8.2 of
jaroslav@56
    67
 * <cite>The Java&trade; Language Specification</cite>.
jaroslav@56
    68
 * For example:
jaroslav@56
    69
 *
jaroslav@56
    70
 * <p> <blockquote>
jaroslav@56
    71
 *     {@code System.out.println("The name of class Foo is: "+Foo.class.getName());}
jaroslav@56
    72
 * </blockquote>
jaroslav@56
    73
 *
jaroslav@56
    74
 * @param <T> the type of the class modeled by this {@code Class}
jaroslav@56
    75
 * object.  For example, the type of {@code String.class} is {@code
jaroslav@56
    76
 * Class<String>}.  Use {@code Class<?>} if the class being modeled is
jaroslav@56
    77
 * unknown.
jaroslav@56
    78
 *
jaroslav@56
    79
 * @author  unascribed
jaroslav@56
    80
 * @see     java.lang.ClassLoader#defineClass(byte[], int, int)
jaroslav@56
    81
 * @since   JDK1.0
jaroslav@56
    82
 */
jaroslav@56
    83
public final
jaroslav@260
    84
    class Class<T> implements java.io.Serializable,
jaroslav@260
    85
                              java.lang.reflect.GenericDeclaration,
jaroslav@260
    86
                              java.lang.reflect.Type,
jaroslav@260
    87
                              java.lang.reflect.AnnotatedElement {
jaroslav@56
    88
    private static final int ANNOTATION= 0x00002000;
jaroslav@56
    89
    private static final int ENUM      = 0x00004000;
jaroslav@56
    90
    private static final int SYNTHETIC = 0x00001000;
jaroslav@56
    91
jaroslav@56
    92
    /*
jaroslav@56
    93
     * Constructor. Only the Java Virtual Machine creates Class
jaroslav@56
    94
     * objects.
jaroslav@56
    95
     */
jaroslav@56
    96
    private Class() {}
jaroslav@56
    97
jaroslav@56
    98
jaroslav@56
    99
    /**
jaroslav@56
   100
     * Converts the object to a string. The string representation is the
jaroslav@56
   101
     * string "class" or "interface", followed by a space, and then by the
jaroslav@56
   102
     * fully qualified name of the class in the format returned by
jaroslav@56
   103
     * {@code getName}.  If this {@code Class} object represents a
jaroslav@56
   104
     * primitive type, this method returns the name of the primitive type.  If
jaroslav@56
   105
     * this {@code Class} object represents void this method returns
jaroslav@56
   106
     * "void".
jaroslav@56
   107
     *
jaroslav@56
   108
     * @return a string representation of this class object.
jaroslav@56
   109
     */
jaroslav@56
   110
    public String toString() {
jaroslav@56
   111
        return (isInterface() ? "interface " : (isPrimitive() ? "" : "class "))
jaroslav@56
   112
            + getName();
jaroslav@56
   113
    }
jaroslav@56
   114
jaroslav@56
   115
jaroslav@56
   116
    /**
jaroslav@56
   117
     * Returns the {@code Class} object associated with the class or
jaroslav@56
   118
     * interface with the given string name.  Invoking this method is
jaroslav@56
   119
     * equivalent to:
jaroslav@56
   120
     *
jaroslav@56
   121
     * <blockquote>
jaroslav@56
   122
     *  {@code Class.forName(className, true, currentLoader)}
jaroslav@56
   123
     * </blockquote>
jaroslav@56
   124
     *
jaroslav@56
   125
     * where {@code currentLoader} denotes the defining class loader of
jaroslav@56
   126
     * the current class.
jaroslav@56
   127
     *
jaroslav@56
   128
     * <p> For example, the following code fragment returns the
jaroslav@56
   129
     * runtime {@code Class} descriptor for the class named
jaroslav@56
   130
     * {@code java.lang.Thread}:
jaroslav@56
   131
     *
jaroslav@56
   132
     * <blockquote>
jaroslav@56
   133
     *   {@code Class t = Class.forName("java.lang.Thread")}
jaroslav@56
   134
     * </blockquote>
jaroslav@56
   135
     * <p>
jaroslav@56
   136
     * A call to {@code forName("X")} causes the class named
jaroslav@56
   137
     * {@code X} to be initialized.
jaroslav@56
   138
     *
jaroslav@56
   139
     * @param      className   the fully qualified name of the desired class.
jaroslav@56
   140
     * @return     the {@code Class} object for the class with the
jaroslav@56
   141
     *             specified name.
jaroslav@56
   142
     * @exception LinkageError if the linkage fails
jaroslav@56
   143
     * @exception ExceptionInInitializerError if the initialization provoked
jaroslav@56
   144
     *            by this method fails
jaroslav@56
   145
     * @exception ClassNotFoundException if the class cannot be located
jaroslav@56
   146
     */
jaroslav@56
   147
    public static Class<?> forName(String className)
jaroslav@56
   148
                throws ClassNotFoundException {
jaroslav@322
   149
        Class<?> c = loadCls(className, className.replace('.', '_'));
jaroslav@321
   150
        if (c == null) {
jaroslav@400
   151
            throw new ClassNotFoundException(className);
jaroslav@321
   152
        }
jaroslav@321
   153
        return c;
jaroslav@56
   154
    }
jaroslav@321
   155
    
jaroslav@322
   156
    @JavaScriptBody(args = {"n", "c" }, body =
jaroslav@322
   157
        "if (vm[c]) return vm[c].$class;\n"
jaroslav@322
   158
      + "if (vm.loadClass) {\n"
jaroslav@322
   159
      + "  vm.loadClass(n);\n"
jaroslav@322
   160
      + "  if (vm[c]) return vm[c].$class;\n"
jaroslav@322
   161
      + "}\n"
jaroslav@322
   162
      + "return null;"
jaroslav@321
   163
    )
jaroslav@322
   164
    private static native Class<?> loadCls(String n, String c);
jaroslav@56
   165
jaroslav@56
   166
jaroslav@56
   167
    /**
jaroslav@56
   168
     * Creates a new instance of the class represented by this {@code Class}
jaroslav@56
   169
     * object.  The class is instantiated as if by a {@code new}
jaroslav@56
   170
     * expression with an empty argument list.  The class is initialized if it
jaroslav@56
   171
     * has not already been initialized.
jaroslav@56
   172
     *
jaroslav@56
   173
     * <p>Note that this method propagates any exception thrown by the
jaroslav@56
   174
     * nullary constructor, including a checked exception.  Use of
jaroslav@56
   175
     * this method effectively bypasses the compile-time exception
jaroslav@56
   176
     * checking that would otherwise be performed by the compiler.
jaroslav@56
   177
     * The {@link
jaroslav@56
   178
     * java.lang.reflect.Constructor#newInstance(java.lang.Object...)
jaroslav@56
   179
     * Constructor.newInstance} method avoids this problem by wrapping
jaroslav@56
   180
     * any exception thrown by the constructor in a (checked) {@link
jaroslav@56
   181
     * java.lang.reflect.InvocationTargetException}.
jaroslav@56
   182
     *
jaroslav@56
   183
     * @return     a newly allocated instance of the class represented by this
jaroslav@56
   184
     *             object.
jaroslav@56
   185
     * @exception  IllegalAccessException  if the class or its nullary
jaroslav@56
   186
     *               constructor is not accessible.
jaroslav@56
   187
     * @exception  InstantiationException
jaroslav@56
   188
     *               if this {@code Class} represents an abstract class,
jaroslav@56
   189
     *               an interface, an array class, a primitive type, or void;
jaroslav@56
   190
     *               or if the class has no nullary constructor;
jaroslav@56
   191
     *               or if the instantiation fails for some other reason.
jaroslav@56
   192
     * @exception  ExceptionInInitializerError if the initialization
jaroslav@56
   193
     *               provoked by this method fails.
jaroslav@56
   194
     * @exception  SecurityException
jaroslav@56
   195
     *             If a security manager, <i>s</i>, is present and any of the
jaroslav@56
   196
     *             following conditions is met:
jaroslav@56
   197
     *
jaroslav@56
   198
     *             <ul>
jaroslav@56
   199
     *
jaroslav@56
   200
     *             <li> invocation of
jaroslav@56
   201
     *             {@link SecurityManager#checkMemberAccess
jaroslav@56
   202
     *             s.checkMemberAccess(this, Member.PUBLIC)} denies
jaroslav@56
   203
     *             creation of new instances of this class
jaroslav@56
   204
     *
jaroslav@56
   205
     *             <li> the caller's class loader is not the same as or an
jaroslav@56
   206
     *             ancestor of the class loader for the current class and
jaroslav@56
   207
     *             invocation of {@link SecurityManager#checkPackageAccess
jaroslav@56
   208
     *             s.checkPackageAccess()} denies access to the package
jaroslav@56
   209
     *             of this class
jaroslav@56
   210
     *
jaroslav@56
   211
     *             </ul>
jaroslav@56
   212
     *
jaroslav@56
   213
     */
jaroslav@397
   214
    @JavaScriptBody(args = { "self", "illegal" }, body =
jaroslav@397
   215
          "\nvar c = self.cnstr;"
jaroslav@397
   216
        + "\nif (c['cons__V']) {"
jaroslav@397
   217
        + "\n  if ((c.cons__V.access & 0x1) != 0) {"
jaroslav@397
   218
        + "\n    var inst = c();"
jaroslav@442
   219
        + "\n    c.cons__V.call(inst);"
jaroslav@397
   220
        + "\n    return inst;"
jaroslav@397
   221
        + "\n  }"
jaroslav@397
   222
        + "\n  return illegal;"
jaroslav@397
   223
        + "\n}"
jaroslav@397
   224
        + "\nreturn null;"
jaroslav@231
   225
    )
jaroslav@397
   226
    private static native Object newInstance0(Class<?> self, Object illegal);
jaroslav@397
   227
    
jaroslav@56
   228
    public T newInstance()
jaroslav@56
   229
        throws InstantiationException, IllegalAccessException
jaroslav@56
   230
    {
jaroslav@397
   231
        Object illegal = new Object();
jaroslav@397
   232
        Object inst = newInstance0(this, illegal);
jaroslav@397
   233
        if (inst == null) {
jaroslav@397
   234
            throw new InstantiationException(getName());
jaroslav@397
   235
        }
jaroslav@397
   236
        if (inst == illegal) {
jaroslav@397
   237
            throw new IllegalAccessException();
jaroslav@397
   238
        }
jaroslav@397
   239
        return (T)inst;
jaroslav@56
   240
    }
jaroslav@56
   241
jaroslav@56
   242
    /**
jaroslav@56
   243
     * Determines if the specified {@code Object} is assignment-compatible
jaroslav@56
   244
     * with the object represented by this {@code Class}.  This method is
jaroslav@56
   245
     * the dynamic equivalent of the Java language {@code instanceof}
jaroslav@56
   246
     * operator. The method returns {@code true} if the specified
jaroslav@56
   247
     * {@code Object} argument is non-null and can be cast to the
jaroslav@56
   248
     * reference type represented by this {@code Class} object without
jaroslav@56
   249
     * raising a {@code ClassCastException.} It returns {@code false}
jaroslav@56
   250
     * otherwise.
jaroslav@56
   251
     *
jaroslav@56
   252
     * <p> Specifically, if this {@code Class} object represents a
jaroslav@56
   253
     * declared class, this method returns {@code true} if the specified
jaroslav@56
   254
     * {@code Object} argument is an instance of the represented class (or
jaroslav@56
   255
     * of any of its subclasses); it returns {@code false} otherwise. If
jaroslav@56
   256
     * this {@code Class} object represents an array class, this method
jaroslav@56
   257
     * returns {@code true} if the specified {@code Object} argument
jaroslav@56
   258
     * can be converted to an object of the array class by an identity
jaroslav@56
   259
     * conversion or by a widening reference conversion; it returns
jaroslav@56
   260
     * {@code false} otherwise. If this {@code Class} object
jaroslav@56
   261
     * represents an interface, this method returns {@code true} if the
jaroslav@56
   262
     * class or any superclass of the specified {@code Object} argument
jaroslav@56
   263
     * implements this interface; it returns {@code false} otherwise. If
jaroslav@56
   264
     * this {@code Class} object represents a primitive type, this method
jaroslav@56
   265
     * returns {@code false}.
jaroslav@56
   266
     *
jaroslav@56
   267
     * @param   obj the object to check
jaroslav@56
   268
     * @return  true if {@code obj} is an instance of this class
jaroslav@56
   269
     *
jaroslav@56
   270
     * @since JDK1.1
jaroslav@56
   271
     */
jaroslav@434
   272
    public boolean isInstance(Object obj) {
jaroslav@434
   273
        String prop = "$instOf_" + getName().replace('.', '_');
jaroslav@434
   274
        return hasProperty(obj, prop);
jaroslav@434
   275
    }
jaroslav@434
   276
    
jaroslav@434
   277
    @JavaScriptBody(args = { "who", "prop" }, body = 
jaroslav@434
   278
        "if (who[prop]) return true; else return false;"
jaroslav@434
   279
    )
jaroslav@434
   280
    private static native boolean hasProperty(Object who, String prop);
jaroslav@56
   281
jaroslav@56
   282
jaroslav@56
   283
    /**
jaroslav@56
   284
     * Determines if the class or interface represented by this
jaroslav@56
   285
     * {@code Class} object is either the same as, or is a superclass or
jaroslav@56
   286
     * superinterface of, the class or interface represented by the specified
jaroslav@56
   287
     * {@code Class} parameter. It returns {@code true} if so;
jaroslav@56
   288
     * otherwise it returns {@code false}. If this {@code Class}
jaroslav@56
   289
     * object represents a primitive type, this method returns
jaroslav@56
   290
     * {@code true} if the specified {@code Class} parameter is
jaroslav@56
   291
     * exactly this {@code Class} object; otherwise it returns
jaroslav@56
   292
     * {@code false}.
jaroslav@56
   293
     *
jaroslav@56
   294
     * <p> Specifically, this method tests whether the type represented by the
jaroslav@56
   295
     * specified {@code Class} parameter can be converted to the type
jaroslav@56
   296
     * represented by this {@code Class} object via an identity conversion
jaroslav@56
   297
     * or via a widening reference conversion. See <em>The Java Language
jaroslav@56
   298
     * Specification</em>, sections 5.1.1 and 5.1.4 , for details.
jaroslav@56
   299
     *
jaroslav@56
   300
     * @param cls the {@code Class} object to be checked
jaroslav@56
   301
     * @return the {@code boolean} value indicating whether objects of the
jaroslav@56
   302
     * type {@code cls} can be assigned to objects of this class
jaroslav@56
   303
     * @exception NullPointerException if the specified Class parameter is
jaroslav@56
   304
     *            null.
jaroslav@56
   305
     * @since JDK1.1
jaroslav@56
   306
     */
jaroslav@56
   307
    public native boolean isAssignableFrom(Class<?> cls);
jaroslav@56
   308
jaroslav@56
   309
jaroslav@56
   310
    /**
jaroslav@56
   311
     * Determines if the specified {@code Class} object represents an
jaroslav@56
   312
     * interface type.
jaroslav@56
   313
     *
jaroslav@56
   314
     * @return  {@code true} if this object represents an interface;
jaroslav@56
   315
     *          {@code false} otherwise.
jaroslav@56
   316
     */
jaroslav@355
   317
    public boolean isInterface() {
jaroslav@355
   318
        return (getAccess() & 0x200) != 0;
jaroslav@355
   319
    }
jaroslav@355
   320
    
jaroslav@443
   321
    @JavaScriptBody(args = {}, body = "return this.access;")
jaroslav@355
   322
    private native int getAccess();
jaroslav@56
   323
jaroslav@56
   324
jaroslav@56
   325
    /**
jaroslav@56
   326
     * Determines if this {@code Class} object represents an array class.
jaroslav@56
   327
     *
jaroslav@56
   328
     * @return  {@code true} if this object represents an array class;
jaroslav@56
   329
     *          {@code false} otherwise.
jaroslav@56
   330
     * @since   JDK1.1
jaroslav@56
   331
     */
jaroslav@228
   332
    public boolean isArray() {
jaroslav@228
   333
        return false;
jaroslav@228
   334
    }
jaroslav@56
   335
jaroslav@56
   336
jaroslav@56
   337
    /**
jaroslav@56
   338
     * Determines if the specified {@code Class} object represents a
jaroslav@56
   339
     * primitive type.
jaroslav@56
   340
     *
jaroslav@56
   341
     * <p> There are nine predefined {@code Class} objects to represent
jaroslav@56
   342
     * the eight primitive types and void.  These are created by the Java
jaroslav@56
   343
     * Virtual Machine, and have the same names as the primitive types that
jaroslav@56
   344
     * they represent, namely {@code boolean}, {@code byte},
jaroslav@56
   345
     * {@code char}, {@code short}, {@code int},
jaroslav@56
   346
     * {@code long}, {@code float}, and {@code double}.
jaroslav@56
   347
     *
jaroslav@56
   348
     * <p> These objects may only be accessed via the following public static
jaroslav@56
   349
     * final variables, and are the only {@code Class} objects for which
jaroslav@56
   350
     * this method returns {@code true}.
jaroslav@56
   351
     *
jaroslav@56
   352
     * @return true if and only if this class represents a primitive type
jaroslav@56
   353
     *
jaroslav@56
   354
     * @see     java.lang.Boolean#TYPE
jaroslav@56
   355
     * @see     java.lang.Character#TYPE
jaroslav@56
   356
     * @see     java.lang.Byte#TYPE
jaroslav@56
   357
     * @see     java.lang.Short#TYPE
jaroslav@56
   358
     * @see     java.lang.Integer#TYPE
jaroslav@56
   359
     * @see     java.lang.Long#TYPE
jaroslav@56
   360
     * @see     java.lang.Float#TYPE
jaroslav@56
   361
     * @see     java.lang.Double#TYPE
jaroslav@56
   362
     * @see     java.lang.Void#TYPE
jaroslav@56
   363
     * @since JDK1.1
jaroslav@56
   364
     */
jaroslav@443
   365
    @JavaScriptBody(args = {}, body = 
jaroslav@443
   366
           "if (this.primitive) return true;"
jaroslav@354
   367
        + "else return false;"
jaroslav@354
   368
    )
jaroslav@56
   369
    public native boolean isPrimitive();
jaroslav@56
   370
jaroslav@56
   371
    /**
jaroslav@56
   372
     * Returns true if this {@code Class} object represents an annotation
jaroslav@56
   373
     * type.  Note that if this method returns true, {@link #isInterface()}
jaroslav@56
   374
     * would also return true, as all annotation types are also interfaces.
jaroslav@56
   375
     *
jaroslav@56
   376
     * @return {@code true} if this class object represents an annotation
jaroslav@56
   377
     *      type; {@code false} otherwise
jaroslav@56
   378
     * @since 1.5
jaroslav@56
   379
     */
jaroslav@56
   380
    public boolean isAnnotation() {
jaroslav@56
   381
        return (getModifiers() & ANNOTATION) != 0;
jaroslav@56
   382
    }
jaroslav@56
   383
jaroslav@56
   384
    /**
jaroslav@56
   385
     * Returns {@code true} if this class is a synthetic class;
jaroslav@56
   386
     * returns {@code false} otherwise.
jaroslav@56
   387
     * @return {@code true} if and only if this class is a synthetic class as
jaroslav@56
   388
     *         defined by the Java Language Specification.
jaroslav@56
   389
     * @since 1.5
jaroslav@56
   390
     */
jaroslav@56
   391
    public boolean isSynthetic() {
jaroslav@56
   392
        return (getModifiers() & SYNTHETIC) != 0;
jaroslav@56
   393
    }
jaroslav@56
   394
jaroslav@56
   395
    /**
jaroslav@56
   396
     * Returns the  name of the entity (class, interface, array class,
jaroslav@56
   397
     * primitive type, or void) represented by this {@code Class} object,
jaroslav@56
   398
     * as a {@code String}.
jaroslav@56
   399
     *
jaroslav@56
   400
     * <p> If this class object represents a reference type that is not an
jaroslav@56
   401
     * array type then the binary name of the class is returned, as specified
jaroslav@56
   402
     * by
jaroslav@56
   403
     * <cite>The Java&trade; Language Specification</cite>.
jaroslav@56
   404
     *
jaroslav@56
   405
     * <p> If this class object represents a primitive type or void, then the
jaroslav@56
   406
     * name returned is a {@code String} equal to the Java language
jaroslav@56
   407
     * keyword corresponding to the primitive type or void.
jaroslav@56
   408
     *
jaroslav@56
   409
     * <p> If this class object represents a class of arrays, then the internal
jaroslav@56
   410
     * form of the name consists of the name of the element type preceded by
jaroslav@56
   411
     * one or more '{@code [}' characters representing the depth of the array
jaroslav@56
   412
     * nesting.  The encoding of element type names is as follows:
jaroslav@56
   413
     *
jaroslav@56
   414
     * <blockquote><table summary="Element types and encodings">
jaroslav@56
   415
     * <tr><th> Element Type <th> &nbsp;&nbsp;&nbsp; <th> Encoding
jaroslav@56
   416
     * <tr><td> boolean      <td> &nbsp;&nbsp;&nbsp; <td align=center> Z
jaroslav@56
   417
     * <tr><td> byte         <td> &nbsp;&nbsp;&nbsp; <td align=center> B
jaroslav@56
   418
     * <tr><td> char         <td> &nbsp;&nbsp;&nbsp; <td align=center> C
jaroslav@56
   419
     * <tr><td> class or interface
jaroslav@56
   420
     *                       <td> &nbsp;&nbsp;&nbsp; <td align=center> L<i>classname</i>;
jaroslav@56
   421
     * <tr><td> double       <td> &nbsp;&nbsp;&nbsp; <td align=center> D
jaroslav@56
   422
     * <tr><td> float        <td> &nbsp;&nbsp;&nbsp; <td align=center> F
jaroslav@56
   423
     * <tr><td> int          <td> &nbsp;&nbsp;&nbsp; <td align=center> I
jaroslav@56
   424
     * <tr><td> long         <td> &nbsp;&nbsp;&nbsp; <td align=center> J
jaroslav@56
   425
     * <tr><td> short        <td> &nbsp;&nbsp;&nbsp; <td align=center> S
jaroslav@56
   426
     * </table></blockquote>
jaroslav@56
   427
     *
jaroslav@56
   428
     * <p> The class or interface name <i>classname</i> is the binary name of
jaroslav@56
   429
     * the class specified above.
jaroslav@56
   430
     *
jaroslav@56
   431
     * <p> Examples:
jaroslav@56
   432
     * <blockquote><pre>
jaroslav@56
   433
     * String.class.getName()
jaroslav@56
   434
     *     returns "java.lang.String"
jaroslav@56
   435
     * byte.class.getName()
jaroslav@56
   436
     *     returns "byte"
jaroslav@56
   437
     * (new Object[3]).getClass().getName()
jaroslav@56
   438
     *     returns "[Ljava.lang.Object;"
jaroslav@56
   439
     * (new int[3][4][5][6][7][8][9]).getClass().getName()
jaroslav@56
   440
     *     returns "[[[[[[[I"
jaroslav@56
   441
     * </pre></blockquote>
jaroslav@56
   442
     *
jaroslav@56
   443
     * @return  the name of the class or interface
jaroslav@56
   444
     *          represented by this object.
jaroslav@56
   445
     */
jaroslav@56
   446
    public String getName() {
jaroslav@225
   447
        return jvmName().replace('/', '.');
jaroslav@56
   448
    }
jaroslav@56
   449
jaroslav@443
   450
    @JavaScriptBody(args = {}, body = "return this.jvmName;")
jaroslav@225
   451
    private native String jvmName();
jaroslav@225
   452
jaroslav@260
   453
    
jaroslav@260
   454
    /**
jaroslav@260
   455
     * Returns an array of {@code TypeVariable} objects that represent the
jaroslav@260
   456
     * type variables declared by the generic declaration represented by this
jaroslav@260
   457
     * {@code GenericDeclaration} object, in declaration order.  Returns an
jaroslav@260
   458
     * array of length 0 if the underlying generic declaration declares no type
jaroslav@260
   459
     * variables.
jaroslav@260
   460
     *
jaroslav@260
   461
     * @return an array of {@code TypeVariable} objects that represent
jaroslav@260
   462
     *     the type variables declared by this generic declaration
jaroslav@260
   463
     * @throws java.lang.reflect.GenericSignatureFormatError if the generic
jaroslav@260
   464
     *     signature of this generic declaration does not conform to
jaroslav@260
   465
     *     the format specified in
jaroslav@260
   466
     *     <cite>The Java&trade; Virtual Machine Specification</cite>
jaroslav@260
   467
     * @since 1.5
jaroslav@260
   468
     */
jaroslav@260
   469
    public TypeVariable<Class<T>>[] getTypeParameters() {
jaroslav@260
   470
        throw new UnsupportedOperationException();
jaroslav@260
   471
    }
jaroslav@260
   472
 
jaroslav@56
   473
    /**
jaroslav@56
   474
     * Returns the {@code Class} representing the superclass of the entity
jaroslav@56
   475
     * (class, interface, primitive type or void) represented by this
jaroslav@56
   476
     * {@code Class}.  If this {@code Class} represents either the
jaroslav@56
   477
     * {@code Object} class, an interface, a primitive type, or void, then
jaroslav@56
   478
     * null is returned.  If this object represents an array class then the
jaroslav@56
   479
     * {@code Class} object representing the {@code Object} class is
jaroslav@56
   480
     * returned.
jaroslav@56
   481
     *
jaroslav@56
   482
     * @return the superclass of the class represented by this object.
jaroslav@56
   483
     */
jaroslav@443
   484
    @JavaScriptBody(args = {}, body = "return this.superclass;")
jaroslav@56
   485
    public native Class<? super T> getSuperclass();
jaroslav@56
   486
jaroslav@56
   487
    /**
jaroslav@56
   488
     * Returns the Java language modifiers for this class or interface, encoded
jaroslav@56
   489
     * in an integer. The modifiers consist of the Java Virtual Machine's
jaroslav@56
   490
     * constants for {@code public}, {@code protected},
jaroslav@56
   491
     * {@code private}, {@code final}, {@code static},
jaroslav@56
   492
     * {@code abstract} and {@code interface}; they should be decoded
jaroslav@56
   493
     * using the methods of class {@code Modifier}.
jaroslav@56
   494
     *
jaroslav@56
   495
     * <p> If the underlying class is an array class, then its
jaroslav@56
   496
     * {@code public}, {@code private} and {@code protected}
jaroslav@56
   497
     * modifiers are the same as those of its component type.  If this
jaroslav@56
   498
     * {@code Class} represents a primitive type or void, its
jaroslav@56
   499
     * {@code public} modifier is always {@code true}, and its
jaroslav@56
   500
     * {@code protected} and {@code private} modifiers are always
jaroslav@56
   501
     * {@code false}. If this object represents an array class, a
jaroslav@56
   502
     * primitive type or void, then its {@code final} modifier is always
jaroslav@56
   503
     * {@code true} and its interface modifier is always
jaroslav@56
   504
     * {@code false}. The values of its other modifiers are not determined
jaroslav@56
   505
     * by this specification.
jaroslav@56
   506
     *
jaroslav@56
   507
     * <p> The modifier encodings are defined in <em>The Java Virtual Machine
jaroslav@56
   508
     * Specification</em>, table 4.1.
jaroslav@56
   509
     *
jaroslav@56
   510
     * @return the {@code int} representing the modifiers for this class
jaroslav@56
   511
     * @see     java.lang.reflect.Modifier
jaroslav@56
   512
     * @since JDK1.1
jaroslav@56
   513
     */
jaroslav@56
   514
    public native int getModifiers();
jaroslav@56
   515
jaroslav@56
   516
jaroslav@56
   517
    /**
jaroslav@56
   518
     * Returns the simple name of the underlying class as given in the
jaroslav@56
   519
     * source code. Returns an empty string if the underlying class is
jaroslav@56
   520
     * anonymous.
jaroslav@56
   521
     *
jaroslav@56
   522
     * <p>The simple name of an array is the simple name of the
jaroslav@56
   523
     * component type with "[]" appended.  In particular the simple
jaroslav@56
   524
     * name of an array whose component type is anonymous is "[]".
jaroslav@56
   525
     *
jaroslav@56
   526
     * @return the simple name of the underlying class
jaroslav@56
   527
     * @since 1.5
jaroslav@56
   528
     */
jaroslav@56
   529
    public String getSimpleName() {
jaroslav@229
   530
        if (isArray())
jaroslav@229
   531
            return getComponentType().getSimpleName()+"[]";
jaroslav@229
   532
jaroslav@229
   533
        String simpleName = getSimpleBinaryName();
jaroslav@229
   534
        if (simpleName == null) { // top level class
jaroslav@229
   535
            simpleName = getName();
jaroslav@229
   536
            return simpleName.substring(simpleName.lastIndexOf(".")+1); // strip the package name
jaroslav@229
   537
        }
jaroslav@229
   538
        // According to JLS3 "Binary Compatibility" (13.1) the binary
jaroslav@229
   539
        // name of non-package classes (not top level) is the binary
jaroslav@229
   540
        // name of the immediately enclosing class followed by a '$' followed by:
jaroslav@229
   541
        // (for nested and inner classes): the simple name.
jaroslav@229
   542
        // (for local classes): 1 or more digits followed by the simple name.
jaroslav@229
   543
        // (for anonymous classes): 1 or more digits.
jaroslav@229
   544
jaroslav@229
   545
        // Since getSimpleBinaryName() will strip the binary name of
jaroslav@229
   546
        // the immediatly enclosing class, we are now looking at a
jaroslav@229
   547
        // string that matches the regular expression "\$[0-9]*"
jaroslav@229
   548
        // followed by a simple name (considering the simple of an
jaroslav@229
   549
        // anonymous class to be the empty string).
jaroslav@229
   550
jaroslav@229
   551
        // Remove leading "\$[0-9]*" from the name
jaroslav@229
   552
        int length = simpleName.length();
jaroslav@229
   553
        if (length < 1 || simpleName.charAt(0) != '$')
jaroslav@229
   554
            throw new IllegalStateException("Malformed class name");
jaroslav@229
   555
        int index = 1;
jaroslav@229
   556
        while (index < length && isAsciiDigit(simpleName.charAt(index)))
jaroslav@229
   557
            index++;
jaroslav@229
   558
        // Eventually, this is the empty string iff this is an anonymous class
jaroslav@229
   559
        return simpleName.substring(index);
jaroslav@56
   560
    }
jaroslav@56
   561
jaroslav@56
   562
    /**
jaroslav@229
   563
     * Returns the "simple binary name" of the underlying class, i.e.,
jaroslav@229
   564
     * the binary name without the leading enclosing class name.
jaroslav@229
   565
     * Returns {@code null} if the underlying class is a top level
jaroslav@229
   566
     * class.
jaroslav@229
   567
     */
jaroslav@229
   568
    private String getSimpleBinaryName() {
jaroslav@229
   569
        Class<?> enclosingClass = null; // XXX getEnclosingClass();
jaroslav@229
   570
        if (enclosingClass == null) // top level class
jaroslav@229
   571
            return null;
jaroslav@229
   572
        // Otherwise, strip the enclosing class' name
jaroslav@229
   573
        try {
jaroslav@229
   574
            return getName().substring(enclosingClass.getName().length());
jaroslav@229
   575
        } catch (IndexOutOfBoundsException ex) {
jaroslav@229
   576
            throw new IllegalStateException("Malformed class name");
jaroslav@229
   577
        }
jaroslav@229
   578
    }
jaroslav@261
   579
jaroslav@261
   580
    /**
jaroslav@261
   581
     * Returns an array containing {@code Field} objects reflecting all
jaroslav@261
   582
     * the accessible public fields of the class or interface represented by
jaroslav@261
   583
     * this {@code Class} object.  The elements in the array returned are
jaroslav@261
   584
     * not sorted and are not in any particular order.  This method returns an
jaroslav@261
   585
     * array of length 0 if the class or interface has no accessible public
jaroslav@261
   586
     * fields, or if it represents an array class, a primitive type, or void.
jaroslav@261
   587
     *
jaroslav@261
   588
     * <p> Specifically, if this {@code Class} object represents a class,
jaroslav@261
   589
     * this method returns the public fields of this class and of all its
jaroslav@261
   590
     * superclasses.  If this {@code Class} object represents an
jaroslav@261
   591
     * interface, this method returns the fields of this interface and of all
jaroslav@261
   592
     * its superinterfaces.
jaroslav@261
   593
     *
jaroslav@261
   594
     * <p> The implicit length field for array class is not reflected by this
jaroslav@261
   595
     * method. User code should use the methods of class {@code Array} to
jaroslav@261
   596
     * manipulate arrays.
jaroslav@261
   597
     *
jaroslav@261
   598
     * <p> See <em>The Java Language Specification</em>, sections 8.2 and 8.3.
jaroslav@261
   599
     *
jaroslav@261
   600
     * @return the array of {@code Field} objects representing the
jaroslav@261
   601
     * public fields
jaroslav@261
   602
     * @exception  SecurityException
jaroslav@261
   603
     *             If a security manager, <i>s</i>, is present and any of the
jaroslav@261
   604
     *             following conditions is met:
jaroslav@261
   605
     *
jaroslav@261
   606
     *             <ul>
jaroslav@261
   607
     *
jaroslav@261
   608
     *             <li> invocation of
jaroslav@261
   609
     *             {@link SecurityManager#checkMemberAccess
jaroslav@261
   610
     *             s.checkMemberAccess(this, Member.PUBLIC)} denies
jaroslav@261
   611
     *             access to the fields within this class
jaroslav@261
   612
     *
jaroslav@261
   613
     *             <li> the caller's class loader is not the same as or an
jaroslav@261
   614
     *             ancestor of the class loader for the current class and
jaroslav@261
   615
     *             invocation of {@link SecurityManager#checkPackageAccess
jaroslav@261
   616
     *             s.checkPackageAccess()} denies access to the package
jaroslav@261
   617
     *             of this class
jaroslav@261
   618
     *
jaroslav@261
   619
     *             </ul>
jaroslav@261
   620
     *
jaroslav@261
   621
     * @since JDK1.1
jaroslav@261
   622
     */
jaroslav@261
   623
    public Field[] getFields() throws SecurityException {
jaroslav@261
   624
        throw new SecurityException();
jaroslav@261
   625
    }
jaroslav@261
   626
jaroslav@261
   627
    /**
jaroslav@261
   628
     * Returns an array containing {@code Method} objects reflecting all
jaroslav@261
   629
     * the public <em>member</em> methods of the class or interface represented
jaroslav@261
   630
     * by this {@code Class} object, including those declared by the class
jaroslav@261
   631
     * or interface and those inherited from superclasses and
jaroslav@261
   632
     * superinterfaces.  Array classes return all the (public) member methods
jaroslav@261
   633
     * inherited from the {@code Object} class.  The elements in the array
jaroslav@261
   634
     * returned are not sorted and are not in any particular order.  This
jaroslav@261
   635
     * method returns an array of length 0 if this {@code Class} object
jaroslav@261
   636
     * represents a class or interface that has no public member methods, or if
jaroslav@261
   637
     * this {@code Class} object represents a primitive type or void.
jaroslav@261
   638
     *
jaroslav@261
   639
     * <p> The class initialization method {@code <clinit>} is not
jaroslav@261
   640
     * included in the returned array. If the class declares multiple public
jaroslav@261
   641
     * member methods with the same parameter types, they are all included in
jaroslav@261
   642
     * the returned array.
jaroslav@261
   643
     *
jaroslav@261
   644
     * <p> See <em>The Java Language Specification</em>, sections 8.2 and 8.4.
jaroslav@261
   645
     *
jaroslav@261
   646
     * @return the array of {@code Method} objects representing the
jaroslav@261
   647
     * public methods of this class
jaroslav@261
   648
     * @exception  SecurityException
jaroslav@261
   649
     *             If a security manager, <i>s</i>, is present and any of the
jaroslav@261
   650
     *             following conditions is met:
jaroslav@261
   651
     *
jaroslav@261
   652
     *             <ul>
jaroslav@261
   653
     *
jaroslav@261
   654
     *             <li> invocation of
jaroslav@261
   655
     *             {@link SecurityManager#checkMemberAccess
jaroslav@261
   656
     *             s.checkMemberAccess(this, Member.PUBLIC)} denies
jaroslav@261
   657
     *             access to the methods within this class
jaroslav@261
   658
     *
jaroslav@261
   659
     *             <li> the caller's class loader is not the same as or an
jaroslav@261
   660
     *             ancestor of the class loader for the current class and
jaroslav@261
   661
     *             invocation of {@link SecurityManager#checkPackageAccess
jaroslav@261
   662
     *             s.checkPackageAccess()} denies access to the package
jaroslav@261
   663
     *             of this class
jaroslav@261
   664
     *
jaroslav@261
   665
     *             </ul>
jaroslav@261
   666
     *
jaroslav@261
   667
     * @since JDK1.1
jaroslav@261
   668
     */
jaroslav@261
   669
    public Method[] getMethods() throws SecurityException {
jaroslav@392
   670
        return MethodImpl.findMethods(this, 0x01);
jaroslav@261
   671
    }
jaroslav@261
   672
jaroslav@261
   673
    /**
jaroslav@261
   674
     * Returns a {@code Field} object that reflects the specified public
jaroslav@261
   675
     * member field of the class or interface represented by this
jaroslav@261
   676
     * {@code Class} object. The {@code name} parameter is a
jaroslav@261
   677
     * {@code String} specifying the simple name of the desired field.
jaroslav@261
   678
     *
jaroslav@261
   679
     * <p> The field to be reflected is determined by the algorithm that
jaroslav@261
   680
     * follows.  Let C be the class represented by this object:
jaroslav@261
   681
     * <OL>
jaroslav@261
   682
     * <LI> If C declares a public field with the name specified, that is the
jaroslav@261
   683
     *      field to be reflected.</LI>
jaroslav@261
   684
     * <LI> If no field was found in step 1 above, this algorithm is applied
jaroslav@261
   685
     *      recursively to each direct superinterface of C. The direct
jaroslav@261
   686
     *      superinterfaces are searched in the order they were declared.</LI>
jaroslav@261
   687
     * <LI> If no field was found in steps 1 and 2 above, and C has a
jaroslav@261
   688
     *      superclass S, then this algorithm is invoked recursively upon S.
jaroslav@261
   689
     *      If C has no superclass, then a {@code NoSuchFieldException}
jaroslav@261
   690
     *      is thrown.</LI>
jaroslav@261
   691
     * </OL>
jaroslav@261
   692
     *
jaroslav@261
   693
     * <p> See <em>The Java Language Specification</em>, sections 8.2 and 8.3.
jaroslav@261
   694
     *
jaroslav@261
   695
     * @param name the field name
jaroslav@261
   696
     * @return  the {@code Field} object of this class specified by
jaroslav@261
   697
     * {@code name}
jaroslav@261
   698
     * @exception NoSuchFieldException if a field with the specified name is
jaroslav@261
   699
     *              not found.
jaroslav@261
   700
     * @exception NullPointerException if {@code name} is {@code null}
jaroslav@261
   701
     * @exception  SecurityException
jaroslav@261
   702
     *             If a security manager, <i>s</i>, is present and any of the
jaroslav@261
   703
     *             following conditions is met:
jaroslav@261
   704
     *
jaroslav@261
   705
     *             <ul>
jaroslav@261
   706
     *
jaroslav@261
   707
     *             <li> invocation of
jaroslav@261
   708
     *             {@link SecurityManager#checkMemberAccess
jaroslav@261
   709
     *             s.checkMemberAccess(this, Member.PUBLIC)} denies
jaroslav@261
   710
     *             access to the field
jaroslav@261
   711
     *
jaroslav@261
   712
     *             <li> the caller's class loader is not the same as or an
jaroslav@261
   713
     *             ancestor of the class loader for the current class and
jaroslav@261
   714
     *             invocation of {@link SecurityManager#checkPackageAccess
jaroslav@261
   715
     *             s.checkPackageAccess()} denies access to the package
jaroslav@261
   716
     *             of this class
jaroslav@261
   717
     *
jaroslav@261
   718
     *             </ul>
jaroslav@261
   719
     *
jaroslav@261
   720
     * @since JDK1.1
jaroslav@261
   721
     */
jaroslav@261
   722
    public Field getField(String name)
jaroslav@261
   723
        throws SecurityException {
jaroslav@261
   724
        throw new SecurityException();
jaroslav@261
   725
    }
jaroslav@229
   726
    
jaroslav@261
   727
    
jaroslav@261
   728
    /**
jaroslav@261
   729
     * Returns a {@code Method} object that reflects the specified public
jaroslav@261
   730
     * member method of the class or interface represented by this
jaroslav@261
   731
     * {@code Class} object. The {@code name} parameter is a
jaroslav@261
   732
     * {@code String} specifying the simple name of the desired method. The
jaroslav@261
   733
     * {@code parameterTypes} parameter is an array of {@code Class}
jaroslav@261
   734
     * objects that identify the method's formal parameter types, in declared
jaroslav@261
   735
     * order. If {@code parameterTypes} is {@code null}, it is
jaroslav@261
   736
     * treated as if it were an empty array.
jaroslav@261
   737
     *
jaroslav@261
   738
     * <p> If the {@code name} is "{@code <init>};"or "{@code <clinit>}" a
jaroslav@261
   739
     * {@code NoSuchMethodException} is raised. Otherwise, the method to
jaroslav@261
   740
     * be reflected is determined by the algorithm that follows.  Let C be the
jaroslav@261
   741
     * class represented by this object:
jaroslav@261
   742
     * <OL>
jaroslav@261
   743
     * <LI> C is searched for any <I>matching methods</I>. If no matching
jaroslav@261
   744
     *      method is found, the algorithm of step 1 is invoked recursively on
jaroslav@261
   745
     *      the superclass of C.</LI>
jaroslav@261
   746
     * <LI> If no method was found in step 1 above, the superinterfaces of C
jaroslav@261
   747
     *      are searched for a matching method. If any such method is found, it
jaroslav@261
   748
     *      is reflected.</LI>
jaroslav@261
   749
     * </OL>
jaroslav@261
   750
     *
jaroslav@261
   751
     * To find a matching method in a class C:&nbsp; If C declares exactly one
jaroslav@261
   752
     * public method with the specified name and exactly the same formal
jaroslav@261
   753
     * parameter types, that is the method reflected. If more than one such
jaroslav@261
   754
     * method is found in C, and one of these methods has a return type that is
jaroslav@261
   755
     * more specific than any of the others, that method is reflected;
jaroslav@261
   756
     * otherwise one of the methods is chosen arbitrarily.
jaroslav@261
   757
     *
jaroslav@261
   758
     * <p>Note that there may be more than one matching method in a
jaroslav@261
   759
     * class because while the Java language forbids a class to
jaroslav@261
   760
     * declare multiple methods with the same signature but different
jaroslav@261
   761
     * return types, the Java virtual machine does not.  This
jaroslav@261
   762
     * increased flexibility in the virtual machine can be used to
jaroslav@261
   763
     * implement various language features.  For example, covariant
jaroslav@261
   764
     * returns can be implemented with {@linkplain
jaroslav@261
   765
     * java.lang.reflect.Method#isBridge bridge methods}; the bridge
jaroslav@261
   766
     * method and the method being overridden would have the same
jaroslav@261
   767
     * signature but different return types.
jaroslav@261
   768
     *
jaroslav@261
   769
     * <p> See <em>The Java Language Specification</em>, sections 8.2 and 8.4.
jaroslav@261
   770
     *
jaroslav@261
   771
     * @param name the name of the method
jaroslav@261
   772
     * @param parameterTypes the list of parameters
jaroslav@261
   773
     * @return the {@code Method} object that matches the specified
jaroslav@261
   774
     * {@code name} and {@code parameterTypes}
jaroslav@261
   775
     * @exception NoSuchMethodException if a matching method is not found
jaroslav@261
   776
     *            or if the name is "&lt;init&gt;"or "&lt;clinit&gt;".
jaroslav@261
   777
     * @exception NullPointerException if {@code name} is {@code null}
jaroslav@261
   778
     * @exception  SecurityException
jaroslav@261
   779
     *             If a security manager, <i>s</i>, is present and any of the
jaroslav@261
   780
     *             following conditions is met:
jaroslav@261
   781
     *
jaroslav@261
   782
     *             <ul>
jaroslav@261
   783
     *
jaroslav@261
   784
     *             <li> invocation of
jaroslav@261
   785
     *             {@link SecurityManager#checkMemberAccess
jaroslav@261
   786
     *             s.checkMemberAccess(this, Member.PUBLIC)} denies
jaroslav@261
   787
     *             access to the method
jaroslav@261
   788
     *
jaroslav@261
   789
     *             <li> the caller's class loader is not the same as or an
jaroslav@261
   790
     *             ancestor of the class loader for the current class and
jaroslav@261
   791
     *             invocation of {@link SecurityManager#checkPackageAccess
jaroslav@261
   792
     *             s.checkPackageAccess()} denies access to the package
jaroslav@261
   793
     *             of this class
jaroslav@261
   794
     *
jaroslav@261
   795
     *             </ul>
jaroslav@261
   796
     *
jaroslav@261
   797
     * @since JDK1.1
jaroslav@261
   798
     */
jaroslav@261
   799
    public Method getMethod(String name, Class<?>... parameterTypes)
jaroslav@420
   800
        throws SecurityException, NoSuchMethodException {
jaroslav@391
   801
        Method m = MethodImpl.findMethod(this, name, parameterTypes);
jaroslav@262
   802
        if (m == null) {
jaroslav@420
   803
            StringBuilder sb = new StringBuilder();
jaroslav@420
   804
            sb.append(getName()).append('.').append(name).append('(');
jaroslav@420
   805
            String sep = "";
jaroslav@420
   806
            for (int i = 0; i < parameterTypes.length; i++) {
jaroslav@420
   807
                sb.append(sep).append(parameterTypes[i].getName());
jaroslav@420
   808
                sep = ", ";
jaroslav@420
   809
            }
jaroslav@420
   810
            sb.append(')');
jaroslav@420
   811
            throw new NoSuchMethodException(sb.toString());
jaroslav@262
   812
        }
jaroslav@262
   813
        return m;
jaroslav@261
   814
    }
jaroslav@261
   815
jaroslav@229
   816
    /**
jaroslav@56
   817
     * Character.isDigit answers {@code true} to some non-ascii
jaroslav@56
   818
     * digits.  This one does not.
jaroslav@56
   819
     */
jaroslav@56
   820
    private static boolean isAsciiDigit(char c) {
jaroslav@56
   821
        return '0' <= c && c <= '9';
jaroslav@56
   822
    }
jaroslav@56
   823
jaroslav@56
   824
    /**
jaroslav@56
   825
     * Returns the canonical name of the underlying class as
jaroslav@56
   826
     * defined by the Java Language Specification.  Returns null if
jaroslav@56
   827
     * the underlying class does not have a canonical name (i.e., if
jaroslav@56
   828
     * it is a local or anonymous class or an array whose component
jaroslav@56
   829
     * type does not have a canonical name).
jaroslav@56
   830
     * @return the canonical name of the underlying class if it exists, and
jaroslav@56
   831
     * {@code null} otherwise.
jaroslav@56
   832
     * @since 1.5
jaroslav@56
   833
     */
jaroslav@56
   834
    public String getCanonicalName() {
jaroslav@228
   835
        if (isArray()) {
jaroslav@228
   836
            String canonicalName = getComponentType().getCanonicalName();
jaroslav@228
   837
            if (canonicalName != null)
jaroslav@228
   838
                return canonicalName + "[]";
jaroslav@228
   839
            else
jaroslav@228
   840
                return null;
jaroslav@228
   841
        }
jaroslav@65
   842
//        if (isLocalOrAnonymousClass())
jaroslav@65
   843
//            return null;
jaroslav@65
   844
//        Class<?> enclosingClass = getEnclosingClass();
jaroslav@228
   845
        Class<?> enclosingClass = null;
jaroslav@228
   846
        if (enclosingClass == null) { // top level class
jaroslav@228
   847
            return getName();
jaroslav@228
   848
        } else {
jaroslav@228
   849
            String enclosingName = enclosingClass.getCanonicalName();
jaroslav@228
   850
            if (enclosingName == null)
jaroslav@228
   851
                return null;
jaroslav@228
   852
            return enclosingName + "." + getSimpleName();
jaroslav@228
   853
        }
jaroslav@56
   854
    }
jaroslav@56
   855
jaroslav@56
   856
    /**
jaroslav@56
   857
     * Finds a resource with a given name.  The rules for searching resources
jaroslav@56
   858
     * associated with a given class are implemented by the defining
jaroslav@56
   859
     * {@linkplain ClassLoader class loader} of the class.  This method
jaroslav@56
   860
     * delegates to this object's class loader.  If this object was loaded by
jaroslav@56
   861
     * the bootstrap class loader, the method delegates to {@link
jaroslav@56
   862
     * ClassLoader#getSystemResourceAsStream}.
jaroslav@56
   863
     *
jaroslav@56
   864
     * <p> Before delegation, an absolute resource name is constructed from the
jaroslav@56
   865
     * given resource name using this algorithm:
jaroslav@56
   866
     *
jaroslav@56
   867
     * <ul>
jaroslav@56
   868
     *
jaroslav@56
   869
     * <li> If the {@code name} begins with a {@code '/'}
jaroslav@56
   870
     * (<tt>'&#92;u002f'</tt>), then the absolute name of the resource is the
jaroslav@56
   871
     * portion of the {@code name} following the {@code '/'}.
jaroslav@56
   872
     *
jaroslav@56
   873
     * <li> Otherwise, the absolute name is of the following form:
jaroslav@56
   874
     *
jaroslav@56
   875
     * <blockquote>
jaroslav@56
   876
     *   {@code modified_package_name/name}
jaroslav@56
   877
     * </blockquote>
jaroslav@56
   878
     *
jaroslav@56
   879
     * <p> Where the {@code modified_package_name} is the package name of this
jaroslav@56
   880
     * object with {@code '/'} substituted for {@code '.'}
jaroslav@56
   881
     * (<tt>'&#92;u002e'</tt>).
jaroslav@56
   882
     *
jaroslav@56
   883
     * </ul>
jaroslav@56
   884
     *
jaroslav@56
   885
     * @param  name name of the desired resource
jaroslav@56
   886
     * @return      A {@link java.io.InputStream} object or {@code null} if
jaroslav@56
   887
     *              no resource with this name is found
jaroslav@56
   888
     * @throws  NullPointerException If {@code name} is {@code null}
jaroslav@56
   889
     * @since  JDK1.1
jaroslav@56
   890
     */
jaroslav@122
   891
     public InputStream getResourceAsStream(String name) {
jaroslav@122
   892
        name = resolveName(name);
jaroslav@424
   893
        byte[] arr = getResourceAsStream0(name);
jaroslav@424
   894
        return arr == null ? null : new ByteArrayInputStream(arr);
jaroslav@424
   895
     }
jaroslav@424
   896
     
jaroslav@424
   897
     @JavaScriptBody(args = "name", body = 
jaroslav@424
   898
         "return (vm.loadBytes) ? vm.loadBytes(name) : null;"
jaroslav@424
   899
     )
jaroslav@424
   900
     private static native byte[] getResourceAsStream0(String name);
jaroslav@56
   901
jaroslav@56
   902
    /**
jaroslav@56
   903
     * Finds a resource with a given name.  The rules for searching resources
jaroslav@56
   904
     * associated with a given class are implemented by the defining
jaroslav@56
   905
     * {@linkplain ClassLoader class loader} of the class.  This method
jaroslav@56
   906
     * delegates to this object's class loader.  If this object was loaded by
jaroslav@56
   907
     * the bootstrap class loader, the method delegates to {@link
jaroslav@56
   908
     * ClassLoader#getSystemResource}.
jaroslav@56
   909
     *
jaroslav@56
   910
     * <p> Before delegation, an absolute resource name is constructed from the
jaroslav@56
   911
     * given resource name using this algorithm:
jaroslav@56
   912
     *
jaroslav@56
   913
     * <ul>
jaroslav@56
   914
     *
jaroslav@56
   915
     * <li> If the {@code name} begins with a {@code '/'}
jaroslav@56
   916
     * (<tt>'&#92;u002f'</tt>), then the absolute name of the resource is the
jaroslav@56
   917
     * portion of the {@code name} following the {@code '/'}.
jaroslav@56
   918
     *
jaroslav@56
   919
     * <li> Otherwise, the absolute name is of the following form:
jaroslav@56
   920
     *
jaroslav@56
   921
     * <blockquote>
jaroslav@56
   922
     *   {@code modified_package_name/name}
jaroslav@56
   923
     * </blockquote>
jaroslav@56
   924
     *
jaroslav@56
   925
     * <p> Where the {@code modified_package_name} is the package name of this
jaroslav@56
   926
     * object with {@code '/'} substituted for {@code '.'}
jaroslav@56
   927
     * (<tt>'&#92;u002e'</tt>).
jaroslav@56
   928
     *
jaroslav@56
   929
     * </ul>
jaroslav@56
   930
     *
jaroslav@56
   931
     * @param  name name of the desired resource
jaroslav@56
   932
     * @return      A  {@link java.net.URL} object or {@code null} if no
jaroslav@56
   933
     *              resource with this name is found
jaroslav@56
   934
     * @since  JDK1.1
jaroslav@56
   935
     */
jaroslav@122
   936
    public java.net.URL getResource(String name) {
jaroslav@122
   937
        name = resolveName(name);
jaroslav@424
   938
        ClassLoader cl = null;
jaroslav@122
   939
        if (cl==null) {
jaroslav@122
   940
            // A system class.
jaroslav@122
   941
            return ClassLoader.getSystemResource(name);
jaroslav@122
   942
        }
jaroslav@122
   943
        return cl.getResource(name);
jaroslav@122
   944
    }
jaroslav@56
   945
jaroslav@56
   946
jaroslav@122
   947
   /**
jaroslav@122
   948
     * Add a package name prefix if the name is not absolute Remove leading "/"
jaroslav@122
   949
     * if name is absolute
jaroslav@122
   950
     */
jaroslav@122
   951
    private String resolveName(String name) {
jaroslav@122
   952
        if (name == null) {
jaroslav@122
   953
            return name;
jaroslav@122
   954
        }
jaroslav@122
   955
        if (!name.startsWith("/")) {
jaroslav@122
   956
            Class<?> c = this;
jaroslav@122
   957
            while (c.isArray()) {
jaroslav@122
   958
                c = c.getComponentType();
jaroslav@122
   959
            }
jaroslav@122
   960
            String baseName = c.getName();
jaroslav@122
   961
            int index = baseName.lastIndexOf('.');
jaroslav@122
   962
            if (index != -1) {
jaroslav@122
   963
                name = baseName.substring(0, index).replace('.', '/')
jaroslav@122
   964
                    +"/"+name;
jaroslav@122
   965
            }
jaroslav@122
   966
        } else {
jaroslav@122
   967
            name = name.substring(1);
jaroslav@122
   968
        }
jaroslav@122
   969
        return name;
jaroslav@122
   970
    }
jaroslav@122
   971
    
jaroslav@122
   972
    /**
jaroslav@122
   973
     * Returns the class loader for the class.  Some implementations may use
jaroslav@122
   974
     * null to represent the bootstrap class loader. This method will return
jaroslav@122
   975
     * null in such implementations if this class was loaded by the bootstrap
jaroslav@122
   976
     * class loader.
jaroslav@122
   977
     *
jaroslav@122
   978
     * <p> If a security manager is present, and the caller's class loader is
jaroslav@122
   979
     * not null and the caller's class loader is not the same as or an ancestor of
jaroslav@122
   980
     * the class loader for the class whose class loader is requested, then
jaroslav@122
   981
     * this method calls the security manager's {@code checkPermission}
jaroslav@122
   982
     * method with a {@code RuntimePermission("getClassLoader")}
jaroslav@122
   983
     * permission to ensure it's ok to access the class loader for the class.
jaroslav@122
   984
     *
jaroslav@122
   985
     * <p>If this object
jaroslav@122
   986
     * represents a primitive type or void, null is returned.
jaroslav@122
   987
     *
jaroslav@122
   988
     * @return  the class loader that loaded the class or interface
jaroslav@122
   989
     *          represented by this object.
jaroslav@122
   990
     * @throws SecurityException
jaroslav@122
   991
     *    if a security manager exists and its
jaroslav@122
   992
     *    {@code checkPermission} method denies
jaroslav@122
   993
     *    access to the class loader for the class.
jaroslav@122
   994
     * @see java.lang.ClassLoader
jaroslav@122
   995
     * @see SecurityManager#checkPermission
jaroslav@122
   996
     * @see java.lang.RuntimePermission
jaroslav@122
   997
     */
jaroslav@122
   998
    public ClassLoader getClassLoader() {
jaroslav@122
   999
        throw new SecurityException();
jaroslav@122
  1000
    }
jaroslav@122
  1001
    
jaroslav@122
  1002
    /**
jaroslav@122
  1003
     * Returns the {@code Class} representing the component type of an
jaroslav@122
  1004
     * array.  If this class does not represent an array class this method
jaroslav@122
  1005
     * returns null.
jaroslav@122
  1006
     *
jaroslav@122
  1007
     * @return the {@code Class} representing the component type of this
jaroslav@122
  1008
     * class if this class is an array
jaroslav@122
  1009
     * @see     java.lang.reflect.Array
jaroslav@122
  1010
     * @since JDK1.1
jaroslav@122
  1011
     */
jaroslav@228
  1012
    public Class<?> getComponentType() {
jaroslav@228
  1013
        return null;
jaroslav@228
  1014
    }
jaroslav@56
  1015
jaroslav@56
  1016
    /**
jaroslav@56
  1017
     * Returns true if and only if this class was declared as an enum in the
jaroslav@56
  1018
     * source code.
jaroslav@56
  1019
     *
jaroslav@56
  1020
     * @return true if and only if this class was declared as an enum in the
jaroslav@56
  1021
     *     source code
jaroslav@56
  1022
     * @since 1.5
jaroslav@56
  1023
     */
jaroslav@56
  1024
    public boolean isEnum() {
jaroslav@56
  1025
        // An enum must both directly extend java.lang.Enum and have
jaroslav@56
  1026
        // the ENUM bit set; classes for specialized enum constants
jaroslav@56
  1027
        // don't do the former.
jaroslav@56
  1028
        return (this.getModifiers() & ENUM) != 0 &&
jaroslav@56
  1029
        this.getSuperclass() == java.lang.Enum.class;
jaroslav@56
  1030
    }
jaroslav@56
  1031
jaroslav@56
  1032
    /**
jaroslav@56
  1033
     * Casts an object to the class or interface represented
jaroslav@56
  1034
     * by this {@code Class} object.
jaroslav@56
  1035
     *
jaroslav@56
  1036
     * @param obj the object to be cast
jaroslav@56
  1037
     * @return the object after casting, or null if obj is null
jaroslav@56
  1038
     *
jaroslav@56
  1039
     * @throws ClassCastException if the object is not
jaroslav@56
  1040
     * null and is not assignable to the type T.
jaroslav@56
  1041
     *
jaroslav@56
  1042
     * @since 1.5
jaroslav@56
  1043
     */
jaroslav@56
  1044
    public T cast(Object obj) {
jaroslav@56
  1045
        if (obj != null && !isInstance(obj))
jaroslav@56
  1046
            throw new ClassCastException(cannotCastMsg(obj));
jaroslav@56
  1047
        return (T) obj;
jaroslav@56
  1048
    }
jaroslav@56
  1049
jaroslav@56
  1050
    private String cannotCastMsg(Object obj) {
jaroslav@56
  1051
        return "Cannot cast " + obj.getClass().getName() + " to " + getName();
jaroslav@56
  1052
    }
jaroslav@56
  1053
jaroslav@56
  1054
    /**
jaroslav@56
  1055
     * Casts this {@code Class} object to represent a subclass of the class
jaroslav@56
  1056
     * represented by the specified class object.  Checks that that the cast
jaroslav@56
  1057
     * is valid, and throws a {@code ClassCastException} if it is not.  If
jaroslav@56
  1058
     * this method succeeds, it always returns a reference to this class object.
jaroslav@56
  1059
     *
jaroslav@56
  1060
     * <p>This method is useful when a client needs to "narrow" the type of
jaroslav@56
  1061
     * a {@code Class} object to pass it to an API that restricts the
jaroslav@56
  1062
     * {@code Class} objects that it is willing to accept.  A cast would
jaroslav@56
  1063
     * generate a compile-time warning, as the correctness of the cast
jaroslav@56
  1064
     * could not be checked at runtime (because generic types are implemented
jaroslav@56
  1065
     * by erasure).
jaroslav@56
  1066
     *
jaroslav@56
  1067
     * @return this {@code Class} object, cast to represent a subclass of
jaroslav@56
  1068
     *    the specified class object.
jaroslav@56
  1069
     * @throws ClassCastException if this {@code Class} object does not
jaroslav@56
  1070
     *    represent a subclass of the specified class (here "subclass" includes
jaroslav@56
  1071
     *    the class itself).
jaroslav@56
  1072
     * @since 1.5
jaroslav@56
  1073
     */
jaroslav@56
  1074
    public <U> Class<? extends U> asSubclass(Class<U> clazz) {
jaroslav@56
  1075
        if (clazz.isAssignableFrom(this))
jaroslav@56
  1076
            return (Class<? extends U>) this;
jaroslav@56
  1077
        else
jaroslav@56
  1078
            throw new ClassCastException(this.toString());
jaroslav@56
  1079
    }
jaroslav@56
  1080
jaroslav@443
  1081
    @JavaScriptBody(args = { "ac" }, 
jaroslav@235
  1082
        body = 
jaroslav@443
  1083
          "if (this.anno) {"
jaroslav@443
  1084
        + "  return this.anno['L' + ac.jvmName + ';'];"
jaroslav@266
  1085
        + "} else return null;"
jaroslav@235
  1086
    )
jaroslav@235
  1087
    private Object getAnnotationData(Class<?> annotationClass) {
jaroslav@235
  1088
        throw new UnsupportedOperationException();
jaroslav@235
  1089
    }
jaroslav@237
  1090
    /**
jaroslav@237
  1091
     * @throws NullPointerException {@inheritDoc}
jaroslav@237
  1092
     * @since 1.5
jaroslav@237
  1093
     */
jaroslav@56
  1094
    public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {
jaroslav@235
  1095
        Object data = getAnnotationData(annotationClass);
jaroslav@235
  1096
        return data == null ? null : AnnotationImpl.create(annotationClass, data);
jaroslav@56
  1097
    }
jaroslav@56
  1098
jaroslav@56
  1099
    /**
jaroslav@56
  1100
     * @throws NullPointerException {@inheritDoc}
jaroslav@56
  1101
     * @since 1.5
jaroslav@56
  1102
     */
jaroslav@443
  1103
    @JavaScriptBody(args = { "ac" }, 
jaroslav@443
  1104
        body = "if (this.anno && this.anno['L' + ac.jvmName + ';']) { return true; }"
jaroslav@235
  1105
        + "else return false;"
jaroslav@235
  1106
    )
jaroslav@56
  1107
    public boolean isAnnotationPresent(
jaroslav@56
  1108
        Class<? extends Annotation> annotationClass) {
jaroslav@56
  1109
        if (annotationClass == null)
jaroslav@56
  1110
            throw new NullPointerException();
jaroslav@56
  1111
jaroslav@56
  1112
        return getAnnotation(annotationClass) != null;
jaroslav@56
  1113
    }
jaroslav@56
  1114
jaroslav@443
  1115
    @JavaScriptBody(args = {}, body = "return this.anno;")
jaroslav@238
  1116
    private Object getAnnotationData() {
jaroslav@238
  1117
        throw new UnsupportedOperationException();
jaroslav@238
  1118
    }
jaroslav@56
  1119
jaroslav@56
  1120
    /**
jaroslav@56
  1121
     * @since 1.5
jaroslav@56
  1122
     */
jaroslav@56
  1123
    public Annotation[] getAnnotations() {
jaroslav@238
  1124
        Object data = getAnnotationData();
jaroslav@238
  1125
        return data == null ? new Annotation[0] : AnnotationImpl.create(data);
jaroslav@56
  1126
    }
jaroslav@56
  1127
jaroslav@56
  1128
    /**
jaroslav@56
  1129
     * @since 1.5
jaroslav@56
  1130
     */
jaroslav@56
  1131
    public Annotation[] getDeclaredAnnotations()  {
jaroslav@65
  1132
        throw new UnsupportedOperationException();
jaroslav@56
  1133
    }
jaroslav@56
  1134
jaroslav@353
  1135
    @JavaScriptBody(args = "type", body = ""
jaroslav@353
  1136
        + "var c = vm.java_lang_Class(true);"
jaroslav@353
  1137
        + "c.jvmName = type;"
jaroslav@354
  1138
        + "c.primitive = true;"
jaroslav@353
  1139
        + "return c;"
jaroslav@353
  1140
    )
jaroslav@353
  1141
    native static Class getPrimitiveClass(String type);
jaroslav@88
  1142
jaroslav@88
  1143
    public boolean desiredAssertionStatus() {
jaroslav@88
  1144
        return false;
jaroslav@88
  1145
    }
jaroslav@56
  1146
}