diff -r 70c062dbd783 -r 05224402145d emul/mini/src/main/java/java/lang/Class.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/emul/mini/src/main/java/java/lang/Class.java Wed Jan 23 20:39:23 2013 +0100 @@ -0,0 +1,1205 @@ +/* + * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.lang; + +import java.io.ByteArrayInputStream; +import org.apidesign.bck2brwsr.emul.AnnotationImpl; +import java.io.InputStream; +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.TypeVariable; +import org.apidesign.bck2brwsr.core.JavaScriptBody; +import org.apidesign.bck2brwsr.emul.MethodImpl; + +/** + * Instances of the class {@code Class} represent classes and + * interfaces in a running Java application. An enum is a kind of + * class and an annotation is a kind of interface. Every array also + * belongs to a class that is reflected as a {@code Class} object + * that is shared by all arrays with the same element type and number + * of dimensions. The primitive Java types ({@code boolean}, + * {@code byte}, {@code char}, {@code short}, + * {@code int}, {@code long}, {@code float}, and + * {@code double}), and the keyword {@code void} are also + * represented as {@code Class} objects. + * + *
{@code Class} has no public constructor. Instead {@code Class} + * objects are constructed automatically by the Java Virtual Machine as classes + * are loaded and by calls to the {@code defineClass} method in the class + * loader. + * + *
The following example uses a {@code Class} object to print the + * class name of an object: + * + *
+ * + *+ * void printClassName(Object obj) { + * System.out.println("The class of " + obj + + * " is " + obj.getClass().getName()); + * } + *
It is also possible to get the {@code Class} object for a named + * type (or for void) using a class literal. See Section 15.8.2 of + * The Java™ Language Specification. + * For example: + * + *
+ * {@code System.out.println("The name of class Foo is: "+Foo.class.getName());} + *+ * + * @param
+ * {@code Class.forName(className, true, currentLoader)} + *+ * + * where {@code currentLoader} denotes the defining class loader of + * the current class. + * + *
For example, the following code fragment returns the + * runtime {@code Class} descriptor for the class named + * {@code java.lang.Thread}: + * + *
+ * {@code Class t = Class.forName("java.lang.Thread")} + *+ *
+ * A call to {@code forName("X")} causes the class named + * {@code X} to be initialized. + * + * @param className the fully qualified name of the desired class. + * @return the {@code Class} object for the class with the + * specified name. + * @exception LinkageError if the linkage fails + * @exception ExceptionInInitializerError if the initialization provoked + * by this method fails + * @exception ClassNotFoundException if the class cannot be located + */ + public static Class> forName(String className) + throws ClassNotFoundException { + if (className.startsWith("[")) { + Class> arrType = defineArray(className); + Class> c = arrType; + while (c != null && c.isArray()) { + c = c.getComponentType0(); // verify component type is sane + } + return arrType; + } + Class> c = loadCls(className, className.replace('.', '_')); + if (c == null) { + throw new ClassNotFoundException(className); + } + return c; + } + + @JavaScriptBody(args = {"n", "c" }, body = + "if (vm[c]) return vm[c].$class;\n" + + "if (vm.loadClass) {\n" + + " vm.loadClass(n);\n" + + " if (vm[c]) return vm[c].$class;\n" + + "}\n" + + "return null;" + ) + private static native Class> loadCls(String n, String c); + + + /** + * Creates a new instance of the class represented by this {@code Class} + * object. The class is instantiated as if by a {@code new} + * expression with an empty argument list. The class is initialized if it + * has not already been initialized. + * + *
Note that this method propagates any exception thrown by the + * nullary constructor, including a checked exception. Use of + * this method effectively bypasses the compile-time exception + * checking that would otherwise be performed by the compiler. + * The {@link + * java.lang.reflect.Constructor#newInstance(java.lang.Object...) + * Constructor.newInstance} method avoids this problem by wrapping + * any exception thrown by the constructor in a (checked) {@link + * java.lang.reflect.InvocationTargetException}. + * + * @return a newly allocated instance of the class represented by this + * object. + * @exception IllegalAccessException if the class or its nullary + * constructor is not accessible. + * @exception InstantiationException + * if this {@code Class} represents an abstract class, + * an interface, an array class, a primitive type, or void; + * or if the class has no nullary constructor; + * or if the instantiation fails for some other reason. + * @exception ExceptionInInitializerError if the initialization + * provoked by this method fails. + * @exception SecurityException + * If a security manager, s, is present and any of the + * following conditions is met: + * + *
Specifically, if this {@code Class} object represents a + * declared class, this method returns {@code true} if the specified + * {@code Object} argument is an instance of the represented class (or + * of any of its subclasses); it returns {@code false} otherwise. If + * this {@code Class} object represents an array class, this method + * returns {@code true} if the specified {@code Object} argument + * can be converted to an object of the array class by an identity + * conversion or by a widening reference conversion; it returns + * {@code false} otherwise. If this {@code Class} object + * represents an interface, this method returns {@code true} if the + * class or any superclass of the specified {@code Object} argument + * implements this interface; it returns {@code false} otherwise. If + * this {@code Class} object represents a primitive type, this method + * returns {@code false}. + * + * @param obj the object to check + * @return true if {@code obj} is an instance of this class + * + * @since JDK1.1 + */ + public boolean isInstance(Object obj) { + String prop = "$instOf_" + getName().replace('.', '_'); + return hasProperty(obj, prop); + } + + @JavaScriptBody(args = { "who", "prop" }, body = + "if (who[prop]) return true; else return false;" + ) + private static native boolean hasProperty(Object who, String prop); + + + /** + * Determines if the class or interface represented by this + * {@code Class} object is either the same as, or is a superclass or + * superinterface of, the class or interface represented by the specified + * {@code Class} parameter. It returns {@code true} if so; + * otherwise it returns {@code false}. If this {@code Class} + * object represents a primitive type, this method returns + * {@code true} if the specified {@code Class} parameter is + * exactly this {@code Class} object; otherwise it returns + * {@code false}. + * + *
Specifically, this method tests whether the type represented by the + * specified {@code Class} parameter can be converted to the type + * represented by this {@code Class} object via an identity conversion + * or via a widening reference conversion. See The Java Language + * Specification, sections 5.1.1 and 5.1.4 , for details. + * + * @param cls the {@code Class} object to be checked + * @return the {@code boolean} value indicating whether objects of the + * type {@code cls} can be assigned to objects of this class + * @exception NullPointerException if the specified Class parameter is + * null. + * @since JDK1.1 + */ + public native boolean isAssignableFrom(Class> cls); + + + /** + * Determines if the specified {@code Class} object represents an + * interface type. + * + * @return {@code true} if this object represents an interface; + * {@code false} otherwise. + */ + public boolean isInterface() { + return (getAccess() & 0x200) != 0; + } + + @JavaScriptBody(args = {}, body = "return this.access;") + private native int getAccess(); + + + /** + * Determines if this {@code Class} object represents an array class. + * + * @return {@code true} if this object represents an array class; + * {@code false} otherwise. + * @since JDK1.1 + */ + public boolean isArray() { + return hasProperty(this, "array"); // NOI18N + } + + + /** + * Determines if the specified {@code Class} object represents a + * primitive type. + * + *
There are nine predefined {@code Class} objects to represent + * the eight primitive types and void. These are created by the Java + * Virtual Machine, and have the same names as the primitive types that + * they represent, namely {@code boolean}, {@code byte}, + * {@code char}, {@code short}, {@code int}, + * {@code long}, {@code float}, and {@code double}. + * + *
These objects may only be accessed via the following public static + * final variables, and are the only {@code Class} objects for which + * this method returns {@code true}. + * + * @return true if and only if this class represents a primitive type + * + * @see java.lang.Boolean#TYPE + * @see java.lang.Character#TYPE + * @see java.lang.Byte#TYPE + * @see java.lang.Short#TYPE + * @see java.lang.Integer#TYPE + * @see java.lang.Long#TYPE + * @see java.lang.Float#TYPE + * @see java.lang.Double#TYPE + * @see java.lang.Void#TYPE + * @since JDK1.1 + */ + @JavaScriptBody(args = {}, body = + "if (this.primitive) return true;" + + "else return false;" + ) + public native boolean isPrimitive(); + + /** + * Returns true if this {@code Class} object represents an annotation + * type. Note that if this method returns true, {@link #isInterface()} + * would also return true, as all annotation types are also interfaces. + * + * @return {@code true} if this class object represents an annotation + * type; {@code false} otherwise + * @since 1.5 + */ + public boolean isAnnotation() { + return (getModifiers() & ANNOTATION) != 0; + } + + /** + * Returns {@code true} if this class is a synthetic class; + * returns {@code false} otherwise. + * @return {@code true} if and only if this class is a synthetic class as + * defined by the Java Language Specification. + * @since 1.5 + */ + public boolean isSynthetic() { + return (getModifiers() & SYNTHETIC) != 0; + } + + /** + * Returns the name of the entity (class, interface, array class, + * primitive type, or void) represented by this {@code Class} object, + * as a {@code String}. + * + *
If this class object represents a reference type that is not an + * array type then the binary name of the class is returned, as specified + * by + * The Java™ Language Specification. + * + *
If this class object represents a primitive type or void, then the + * name returned is a {@code String} equal to the Java language + * keyword corresponding to the primitive type or void. + * + *
If this class object represents a class of arrays, then the internal + * form of the name consists of the name of the element type preceded by + * one or more '{@code [}' characters representing the depth of the array + * nesting. The encoding of element type names is as follows: + * + *
+ * + *+ *
Element Type Encoding + * boolean Z + * byte B + * char C + * class or interface + * Lclassname; + * double D + * float F + * int I + * long J + * short S + *
The class or interface name classname is the binary name of + * the class specified above. + * + *
Examples: + *
+ * + * @return the name of the class or interface + * represented by this object. + */ + public String getName() { + return jvmName().replace('/', '.'); + } + + @JavaScriptBody(args = {}, body = "return this.jvmName;") + private native String jvmName(); + + + /** + * Returns an array of {@code TypeVariable} objects that represent the + * type variables declared by the generic declaration represented by this + * {@code GenericDeclaration} object, in declaration order. Returns an + * array of length 0 if the underlying generic declaration declares no type + * variables. + * + * @return an array of {@code TypeVariable} objects that represent + * the type variables declared by this generic declaration + * @throws java.lang.reflect.GenericSignatureFormatError if the generic + * signature of this generic declaration does not conform to + * the format specified in + * The Java™ Virtual Machine Specification + * @since 1.5 + */ + public TypeVariable+ * String.class.getName() + * returns "java.lang.String" + * byte.class.getName() + * returns "byte" + * (new Object[3]).getClass().getName() + * returns "[Ljava.lang.Object;" + * (new int[3][4][5][6][7][8][9]).getClass().getName() + * returns "[[[[[[[I" + *
If the underlying class is an array class, then its + * {@code public}, {@code private} and {@code protected} + * modifiers are the same as those of its component type. If this + * {@code Class} represents a primitive type or void, its + * {@code public} modifier is always {@code true}, and its + * {@code protected} and {@code private} modifiers are always + * {@code false}. If this object represents an array class, a + * primitive type or void, then its {@code final} modifier is always + * {@code true} and its interface modifier is always + * {@code false}. The values of its other modifiers are not determined + * by this specification. + * + *
The modifier encodings are defined in The Java Virtual Machine + * Specification, table 4.1. + * + * @return the {@code int} representing the modifiers for this class + * @see java.lang.reflect.Modifier + * @since JDK1.1 + */ + public native int getModifiers(); + + + /** + * Returns the simple name of the underlying class as given in the + * source code. Returns an empty string if the underlying class is + * anonymous. + * + *
The simple name of an array is the simple name of the + * component type with "[]" appended. In particular the simple + * name of an array whose component type is anonymous is "[]". + * + * @return the simple name of the underlying class + * @since 1.5 + */ + public String getSimpleName() { + if (isArray()) + return getComponentType().getSimpleName()+"[]"; + + String simpleName = getSimpleBinaryName(); + if (simpleName == null) { // top level class + simpleName = getName(); + return simpleName.substring(simpleName.lastIndexOf(".")+1); // strip the package name + } + // According to JLS3 "Binary Compatibility" (13.1) the binary + // name of non-package classes (not top level) is the binary + // name of the immediately enclosing class followed by a '$' followed by: + // (for nested and inner classes): the simple name. + // (for local classes): 1 or more digits followed by the simple name. + // (for anonymous classes): 1 or more digits. + + // Since getSimpleBinaryName() will strip the binary name of + // the immediatly enclosing class, we are now looking at a + // string that matches the regular expression "\$[0-9]*" + // followed by a simple name (considering the simple of an + // anonymous class to be the empty string). + + // Remove leading "\$[0-9]*" from the name + int length = simpleName.length(); + if (length < 1 || simpleName.charAt(0) != '$') + throw new IllegalStateException("Malformed class name"); + int index = 1; + while (index < length && isAsciiDigit(simpleName.charAt(index))) + index++; + // Eventually, this is the empty string iff this is an anonymous class + return simpleName.substring(index); + } + + /** + * Returns the "simple binary name" of the underlying class, i.e., + * the binary name without the leading enclosing class name. + * Returns {@code null} if the underlying class is a top level + * class. + */ + private String getSimpleBinaryName() { + Class> enclosingClass = null; // XXX getEnclosingClass(); + if (enclosingClass == null) // top level class + return null; + // Otherwise, strip the enclosing class' name + try { + return getName().substring(enclosingClass.getName().length()); + } catch (IndexOutOfBoundsException ex) { + throw new IllegalStateException("Malformed class name"); + } + } + + /** + * Returns an array containing {@code Field} objects reflecting all + * the accessible public fields of the class or interface represented by + * this {@code Class} object. The elements in the array returned are + * not sorted and are not in any particular order. This method returns an + * array of length 0 if the class or interface has no accessible public + * fields, or if it represents an array class, a primitive type, or void. + * + *
Specifically, if this {@code Class} object represents a class, + * this method returns the public fields of this class and of all its + * superclasses. If this {@code Class} object represents an + * interface, this method returns the fields of this interface and of all + * its superinterfaces. + * + *
The implicit length field for array class is not reflected by this + * method. User code should use the methods of class {@code Array} to + * manipulate arrays. + * + *
See The Java Language Specification, sections 8.2 and 8.3. + * + * @return the array of {@code Field} objects representing the + * public fields + * @exception SecurityException + * If a security manager, s, is present and any of the + * following conditions is met: + * + *
The class initialization method {@code See The Java Language Specification, sections 8.2 and 8.4.
+ *
+ * @return the array of {@code Method} objects representing the
+ * public methods of this class
+ * @exception SecurityException
+ * If a security manager, s, is present and any of the
+ * following conditions is met:
+ *
+ * The field to be reflected is determined by the algorithm that
+ * follows. Let C be the class represented by this object:
+ * See The Java Language Specification, sections 8.2 and 8.3.
+ *
+ * @param name the field name
+ * @return the {@code Field} object of this class specified by
+ * {@code name}
+ * @exception NoSuchFieldException if a field with the specified name is
+ * not found.
+ * @exception NullPointerException if {@code name} is {@code null}
+ * @exception SecurityException
+ * If a security manager, s, is present and any of the
+ * following conditions is met:
+ *
+ * If the {@code name} is "{@code Note that there may be more than one matching method in a
+ * class because while the Java language forbids a class to
+ * declare multiple methods with the same signature but different
+ * return types, the Java virtual machine does not. This
+ * increased flexibility in the virtual machine can be used to
+ * implement various language features. For example, covariant
+ * returns can be implemented with {@linkplain
+ * java.lang.reflect.Method#isBridge bridge methods}; the bridge
+ * method and the method being overridden would have the same
+ * signature but different return types.
+ *
+ * See The Java Language Specification, sections 8.2 and 8.4.
+ *
+ * @param name the name of the method
+ * @param parameterTypes the list of parameters
+ * @return the {@code Method} object that matches the specified
+ * {@code name} and {@code parameterTypes}
+ * @exception NoSuchMethodException if a matching method is not found
+ * or if the name is "<init>"or "<clinit>".
+ * @exception NullPointerException if {@code name} is {@code null}
+ * @exception SecurityException
+ * If a security manager, s, is present and any of the
+ * following conditions is met:
+ *
+ * Before delegation, an absolute resource name is constructed from the
+ * given resource name using this algorithm:
+ *
+ * Where the {@code modified_package_name} is the package name of this
+ * object with {@code '/'} substituted for {@code '.'}
+ * ('\u002e').
+ *
+ * Before delegation, an absolute resource name is constructed from the
+ * given resource name using this algorithm:
+ *
+ * Where the {@code modified_package_name} is the package name of this
+ * object with {@code '/'} substituted for {@code '.'}
+ * ('\u002e').
+ *
+ * If a security manager is present, and the caller's class loader is
+ * not null and the caller's class loader is not the same as or an ancestor of
+ * the class loader for the class whose class loader is requested, then
+ * this method calls the security manager's {@code checkPermission}
+ * method with a {@code RuntimePermission("getClassLoader")}
+ * permission to ensure it's ok to access the class loader for the class.
+ *
+ * If this object
+ * represents a primitive type or void, null is returned.
+ *
+ * @return the class loader that loaded the class or interface
+ * represented by this object.
+ * @throws SecurityException
+ * if a security manager exists and its
+ * {@code checkPermission} method denies
+ * access to the class loader for the class.
+ * @see java.lang.ClassLoader
+ * @see SecurityManager#checkPermission
+ * @see java.lang.RuntimePermission
+ */
+ public ClassLoader getClassLoader() {
+ throw new SecurityException();
+ }
+
+ /**
+ * Returns the {@code Class} representing the component type of an
+ * array. If this class does not represent an array class this method
+ * returns null.
+ *
+ * @return the {@code Class} representing the component type of this
+ * class if this class is an array
+ * @see java.lang.reflect.Array
+ * @since JDK1.1
+ */
+ public Class> getComponentType() {
+ if (isArray()) {
+ try {
+ return getComponentType0();
+ } catch (ClassNotFoundException cnfe) {
+ throw new IllegalStateException(cnfe);
+ }
+ }
+ return null;
+ }
+
+ private Class> getComponentType0() throws ClassNotFoundException {
+ String n = getName().substring(1);
+ switch (n.charAt(0)) {
+ case 'L':
+ n = n.substring(1, n.length() - 1);
+ return Class.forName(n);
+ case 'I':
+ return Integer.TYPE;
+ case 'J':
+ return Long.TYPE;
+ case 'D':
+ return Double.TYPE;
+ case 'F':
+ return Float.TYPE;
+ case 'B':
+ return Byte.TYPE;
+ case 'Z':
+ return Boolean.TYPE;
+ case 'S':
+ return Short.TYPE;
+ case 'V':
+ return Void.TYPE;
+ case 'C':
+ return Character.TYPE;
+ case '[':
+ return defineArray(n);
+ default:
+ throw new ClassNotFoundException("Unknown component type of " + getName());
+ }
+ }
+
+ @JavaScriptBody(args = { "sig" }, body =
+ "var c = Array[sig];\n" +
+ "if (c) return c;\n" +
+ "c = vm.java_lang_Class(true);\n" +
+ "c.jvmName = sig;\n" +
+ "c.superclass = vm.java_lang_Object(false).$class;\n" +
+ "c.array = true;\n" +
+ "Array[sig] = c;\n" +
+ "return c;"
+ )
+ private static native Class> defineArray(String sig);
+
+ /**
+ * Returns true if and only if this class was declared as an enum in the
+ * source code.
+ *
+ * @return true if and only if this class was declared as an enum in the
+ * source code
+ * @since 1.5
+ */
+ public boolean isEnum() {
+ // An enum must both directly extend java.lang.Enum and have
+ // the ENUM bit set; classes for specialized enum constants
+ // don't do the former.
+ return (this.getModifiers() & ENUM) != 0 &&
+ this.getSuperclass() == java.lang.Enum.class;
+ }
+
+ /**
+ * Casts an object to the class or interface represented
+ * by this {@code Class} object.
+ *
+ * @param obj the object to be cast
+ * @return the object after casting, or null if obj is null
+ *
+ * @throws ClassCastException if the object is not
+ * null and is not assignable to the type T.
+ *
+ * @since 1.5
+ */
+ public T cast(Object obj) {
+ if (obj != null && !isInstance(obj))
+ throw new ClassCastException(cannotCastMsg(obj));
+ return (T) obj;
+ }
+
+ private String cannotCastMsg(Object obj) {
+ return "Cannot cast " + obj.getClass().getName() + " to " + getName();
+ }
+
+ /**
+ * Casts this {@code Class} object to represent a subclass of the class
+ * represented by the specified class object. Checks that that the cast
+ * is valid, and throws a {@code ClassCastException} if it is not. If
+ * this method succeeds, it always returns a reference to this class object.
+ *
+ * This method is useful when a client needs to "narrow" the type of
+ * a {@code Class} object to pass it to an API that restricts the
+ * {@code Class} objects that it is willing to accept. A cast would
+ * generate a compile-time warning, as the correctness of the cast
+ * could not be checked at runtime (because generic types are implemented
+ * by erasure).
+ *
+ * @return this {@code Class} object, cast to represent a subclass of
+ * the specified class object.
+ * @throws ClassCastException if this {@code Class} object does not
+ * represent a subclass of the specified class (here "subclass" includes
+ * the class itself).
+ * @since 1.5
+ */
+ public Class extends U> asSubclass(Class clazz) {
+ if (clazz.isAssignableFrom(this))
+ return (Class extends U>) this;
+ else
+ throw new ClassCastException(this.toString());
+ }
+
+ @JavaScriptBody(args = { "ac" },
+ body =
+ "if (this.anno) {"
+ + " return this.anno['L' + ac.jvmName + ';'];"
+ + "} else return null;"
+ )
+ private Object getAnnotationData(Class> annotationClass) {
+ throw new UnsupportedOperationException();
+ }
+ /**
+ * @throws NullPointerException {@inheritDoc}
+ * @since 1.5
+ */
+ public A getAnnotation(Class annotationClass) {
+ Object data = getAnnotationData(annotationClass);
+ return data == null ? null : AnnotationImpl.create(annotationClass, data);
+ }
+
+ /**
+ * @throws NullPointerException {@inheritDoc}
+ * @since 1.5
+ */
+ @JavaScriptBody(args = { "ac" },
+ body = "if (this.anno && this.anno['L' + ac.jvmName + ';']) { return true; }"
+ + "else return false;"
+ )
+ public boolean isAnnotationPresent(
+ Class extends Annotation> annotationClass) {
+ if (annotationClass == null)
+ throw new NullPointerException();
+
+ return getAnnotation(annotationClass) != null;
+ }
+
+ @JavaScriptBody(args = {}, body = "return this.anno;")
+ private Object getAnnotationData() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @since 1.5
+ */
+ public Annotation[] getAnnotations() {
+ Object data = getAnnotationData();
+ return data == null ? new Annotation[0] : AnnotationImpl.create(data);
+ }
+
+ /**
+ * @since 1.5
+ */
+ public Annotation[] getDeclaredAnnotations() {
+ throw new UnsupportedOperationException();
+ }
+
+ @JavaScriptBody(args = "type", body = ""
+ + "var c = vm.java_lang_Class(true);"
+ + "c.jvmName = type;"
+ + "c.primitive = true;"
+ + "return c;"
+ )
+ native static Class getPrimitiveClass(String type);
+
+ @JavaScriptBody(args = {}, body =
+ "return vm.desiredAssertionStatus ? vm.desiredAssertionStatus : false;"
+ )
+ public native boolean desiredAssertionStatus();
+}
+ *
+ *
+ *
+ * @since JDK1.1
+ */
+ public Method[] getMethods() throws SecurityException {
+ return MethodImpl.findMethods(this, 0x01);
+ }
+
+ /**
+ * Returns a {@code Field} object that reflects the specified public
+ * member field of the class or interface represented by this
+ * {@code Class} object. The {@code name} parameter is a
+ * {@code String} specifying the simple name of the desired field.
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ * @since JDK1.1
+ */
+ public Field getField(String name)
+ throws SecurityException {
+ throw new SecurityException();
+ }
+
+
+ /**
+ * Returns a {@code Method} object that reflects the specified public
+ * member method of the class or interface represented by this
+ * {@code Class} object. The {@code name} parameter is a
+ * {@code String} specifying the simple name of the desired method. The
+ * {@code parameterTypes} parameter is an array of {@code Class}
+ * objects that identify the method's formal parameter types, in declared
+ * order. If {@code parameterTypes} is {@code null}, it is
+ * treated as if it were an empty array.
+ *
+ *
+ *
+ *
+ * To find a matching method in a class C: If C declares exactly one
+ * public method with the specified name and exactly the same formal
+ * parameter types, that is the method reflected. If more than one such
+ * method is found in C, and one of these methods has a return type that is
+ * more specific than any of the others, that method is reflected;
+ * otherwise one of the methods is chosen arbitrarily.
+ *
+ *
+ *
+ *
+ *
+ * @since JDK1.1
+ */
+ public Method getMethod(String name, Class>... parameterTypes)
+ throws SecurityException, NoSuchMethodException {
+ Method m = MethodImpl.findMethod(this, name, parameterTypes);
+ if (m == null) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(getName()).append('.').append(name).append('(');
+ String sep = "";
+ for (int i = 0; i < parameterTypes.length; i++) {
+ sb.append(sep).append(parameterTypes[i].getName());
+ sep = ", ";
+ }
+ sb.append(')');
+ throw new NoSuchMethodException(sb.toString());
+ }
+ return m;
+ }
+
+ /**
+ * Character.isDigit answers {@code true} to some non-ascii
+ * digits. This one does not.
+ */
+ private static boolean isAsciiDigit(char c) {
+ return '0' <= c && c <= '9';
+ }
+
+ /**
+ * Returns the canonical name of the underlying class as
+ * defined by the Java Language Specification. Returns null if
+ * the underlying class does not have a canonical name (i.e., if
+ * it is a local or anonymous class or an array whose component
+ * type does not have a canonical name).
+ * @return the canonical name of the underlying class if it exists, and
+ * {@code null} otherwise.
+ * @since 1.5
+ */
+ public String getCanonicalName() {
+ if (isArray()) {
+ String canonicalName = getComponentType().getCanonicalName();
+ if (canonicalName != null)
+ return canonicalName + "[]";
+ else
+ return null;
+ }
+// if (isLocalOrAnonymousClass())
+// return null;
+// Class> enclosingClass = getEnclosingClass();
+ Class> enclosingClass = null;
+ if (enclosingClass == null) { // top level class
+ return getName();
+ } else {
+ String enclosingName = enclosingClass.getCanonicalName();
+ if (enclosingName == null)
+ return null;
+ return enclosingName + "." + getSimpleName();
+ }
+ }
+
+ /**
+ * Finds a resource with a given name. The rules for searching resources
+ * associated with a given class are implemented by the defining
+ * {@linkplain ClassLoader class loader} of the class. This method
+ * delegates to this object's class loader. If this object was loaded by
+ * the bootstrap class loader, the method delegates to {@link
+ * ClassLoader#getSystemResourceAsStream}.
+ *
+ *
+ *
+ *
+ *
+ * @param name name of the desired resource
+ * @return A {@link java.io.InputStream} object or {@code null} if
+ * no resource with this name is found
+ * @throws NullPointerException If {@code name} is {@code null}
+ * @since JDK1.1
+ */
+ public InputStream getResourceAsStream(String name) {
+ name = resolveName(name);
+ byte[] arr = getResourceAsStream0(name);
+ return arr == null ? null : new ByteArrayInputStream(arr);
+ }
+
+ @JavaScriptBody(args = "name", body =
+ "return (vm.loadBytes) ? vm.loadBytes(name) : null;"
+ )
+ private static native byte[] getResourceAsStream0(String name);
+
+ /**
+ * Finds a resource with a given name. The rules for searching resources
+ * associated with a given class are implemented by the defining
+ * {@linkplain ClassLoader class loader} of the class. This method
+ * delegates to this object's class loader. If this object was loaded by
+ * the bootstrap class loader, the method delegates to {@link
+ * ClassLoader#getSystemResource}.
+ *
+ *
+ * {@code modified_package_name/name}
+ *
+ *
+ *
+ *
+ *
+ *
+ * @param name name of the desired resource
+ * @return A {@link java.net.URL} object or {@code null} if no
+ * resource with this name is found
+ * @since JDK1.1
+ */
+ public java.net.URL getResource(String name) {
+ name = resolveName(name);
+ ClassLoader cl = null;
+ if (cl==null) {
+ // A system class.
+ return ClassLoader.getSystemResource(name);
+ }
+ return cl.getResource(name);
+ }
+
+
+ /**
+ * Add a package name prefix if the name is not absolute Remove leading "/"
+ * if name is absolute
+ */
+ private String resolveName(String name) {
+ if (name == null) {
+ return name;
+ }
+ if (!name.startsWith("/")) {
+ Class> c = this;
+ while (c.isArray()) {
+ c = c.getComponentType();
+ }
+ String baseName = c.getName();
+ int index = baseName.lastIndexOf('.');
+ if (index != -1) {
+ name = baseName.substring(0, index).replace('.', '/')
+ +"/"+name;
+ }
+ } else {
+ name = name.substring(1);
+ }
+ return name;
+ }
+
+ /**
+ * Returns the class loader for the class. Some implementations may use
+ * null to represent the bootstrap class loader. This method will return
+ * null in such implementations if this class was loaded by the bootstrap
+ * class loader.
+ *
+ *
+ * {@code modified_package_name/name}
+ *
+ *
+ *