/* * * * Copyright 1990-2009 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program 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. * * This program 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 at /legal/license.txt). * * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. */ package java.lang; /** * Instances of the class <code>Class</code> represent classes and interfaces * in a running Java application. Every array also belongs to a class that is * reflected as a <code>Class</code> object that is shared by all arrays with * the same element type and number of dimensions. * * <p> <code>Class</code> has no public constructor. Instead <code>Class</code> * objects are constructed automatically by the Java Virtual Machine as classes * are loaded. * * <p> The following example uses a <code>Class</code> object to print the * class name of an object: * * <p> <blockquote><pre> * void printClassName(Object obj) { * System.out.println("The class of " + obj + * " is " + obj.getClass().getName()); * } * </pre></blockquote> * * @version 12/17/01 (CLDC 1.1) * @since JDK1.0, CLDC 1.0 */ public final class Class { /* * Constructor. Only the Java Virtual Machine creates Class * objects. */ private Class() {} /** * Converts the object to a string. The string representation is the * string "class" or "interface", followed by a space, and then by the * fully qualified name of the class in the format returned by * <code>getName</code>. If this <code>Class</code> object represents a * primitive type, this method returns the name of the primitive type. If * this <code>Class</code> object represents void this method returns * "void". * * @return a string representation of this class object. */ public String toString() { return (isInterface() ? "interface " : "class ") + getName(); } /** * Returns the <code>Class</code> object associated with the class * with the given string name. Given the fully-qualified name for * a class or interface, this method attempts to locate, load and * link the class. * <p> * For example, the following code fragment returns the runtime * <code>Class</code> descriptor for the class named * <code>java.lang.Thread</code>: * <ul><code> * Class t = Class.forName("java.lang.Thread") * </code></ul> * * @param className the fully qualified name of the desired class. * @return the <code>Class</code> object for the class with the * specified name. * @exception ClassNotFoundException if the class could not be found. * @exception Error if the function fails for any other reason. * @since JDK1.0 */ // public static native Class forName(String className) // throws ClassNotFoundException; public static Class forName(String className) throws ClassNotFoundException { throw new Error("forName() NYI "); } /** * Creates a new instance of a class. * * @return a newly allocated instance of the class represented by this * object. This is done exactly as if by a <code>new</code> * expression with an empty argument list. * @exception IllegalAccessException if the class or initializer is * not accessible. * @exception InstantiationException if an application tries to * instantiate an abstract class or an interface, or if the * instantiation fails for some other reason. * @since JDK1.0 */ // public native Object newInstance() // throws InstantiationException, IllegalAccessException; public Object newInstance() throws InstantiationException, IllegalAccessException { throw new Error("newInstance() NYI "); } /** * Determines if the specified <code>Object</code> is assignment-compatible * with the object represented by this <code>Class</code>. This method is * the dynamic equivalent of the Java language <code>instanceof</code> * operator. The method returns <code>true</code> if the specified * <code>Object</code> argument is non-null and can be cast to the * reference type represented by this <code>Class</code> object without * raising a <code>ClassCastException.</code> It returns <code>false</code> * otherwise. * * <p> Specifically, if this <code>Class</code> object represents a * declared class, this method returns <code>true</code> if the specified * <code>Object</code> argument is an instance of the represented class (or * of any of its subclasses); it returns <code>false</code> otherwise. If * this <code>Class</code> object represents an array class, this method * returns <code>true</code> if the specified <code>Object</code> 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</code> otherwise. If this <code>Class</code> object * represents an interface, this method returns <code>true</code> if the * class or any superclass of the specified <code>Object</code> argument * implements this interface; it returns <code>false</code> otherwise. If * this <code>Class</code> object represents a primitive type, this method * returns <code>false</code>. * * @param obj the object to check * @return true if <code>obj</code> is an instance of this class * * @since JDK1.1 */ // public native boolean isInstance(Object obj); public boolean isInstance(Object obj) { throw new Error("newInstance() NYI "); } /** * Determines if the class or interface represented by this * <code>Class</code> object is either the same as, or is a superclass or * superinterface of, the class or interface represented by the specified * <code>Class</code> parameter. It returns <code>true</code> if so; * otherwise it returns <code>false</code>. If this <code>Class</code> * object represents a primitive type, this method returns * <code>true</code> if the specified <code>Class</code> parameter is * exactly this <code>Class</code> object; otherwise it returns * <code>false</code>. * * <p> Specifically, this method tests whether the type represented by the * specified <code>Class</code> parameter can be converted to the type * represented by this <code>Class</code> object via an identity conversion * or via a widening reference conversion. See <em>The Java Language * Specification</em>, sections 5.1.1 and 5.1.4 , for details. * * @param cls the <code>Class</code> object to be checked * @return the <code>boolean</code> value indicating whether objects of the * type <code>cls</code> 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); public boolean isAssignableFrom(Class cls) { throw new Error("isAssignableFrom() NYI "); } /** * Determines if the specified <code>Class</code> object represents an * interface type. * * @return <code>true</code> if this object represents an interface; * <code>false</code> otherwise. */ // public native boolean isInterface(); public boolean isInterface() { throw new Error("isAssignableFrom() NYI "); } /** * Determines if this <code>Class</code> object represents an array class. * * @return <code>true</code> if this object represents an array class; * <code>false</code> otherwise. * @since JDK1.1 */ // public native boolean isArray(); public boolean isArray() { throw new Error("isAssignableFrom() NYI "); } /** * Returns the fully-qualified name of the entity (class, interface, array * class, primitive type, or void) represented by this <code>Class</code> * object, as a <code>String</code>. * * <p> If this <code>Class</code> object represents a class of arrays, then * the internal form of the name consists of the name of the element type * in Java signature format, preceded by one or more "<tt>[</tt>" * characters representing the depth of array nesting. Thus: * * <blockquote><pre> * (new Object[3]).getClass().getName() * </pre></blockquote> * * returns "<code>[Ljava.lang.Object;</code>" and: * * <blockquote><pre> * (new int[3][4][5][6][7][8][9]).getClass().getName() * </pre></blockquote> * * returns "<code>[[[[[[[I</code>". The encoding of element type names * is as follows: * * <blockquote><pre> * B byte * C char * D double * F float * I int * J long * L<i>classname;</i> class or interface * S short * Z boolean * </pre></blockquote> * * The class or interface name <tt><i>classname</i></tt> is given in fully * qualified form as shown in the example above. * * @return the fully qualified name of the class or interface * represented by this object. */ // public native String getName(); public String getName() { throw new Error("isAssignableFrom() NYI "); } /** * Finds a resource with a given name in the application's * JAR file. This method returns * <code>null</code> if no resource with this name is found * in the application's JAR file. * <p> * The resource names can be represented in two * different formats: absolute or relative. * <p> * Absolute format: * <ul><code>/packagePathName/resourceName</code></ul> * <p> * Relative format: * <ul><code>resourceName</code></ul> * <p> * In the absolute format, the programmer provides a fully * qualified name that includes both the full path and the * name of the resource inside the JAR file. In the path names, * the character "/" is used as the separator. * <p> * In the relative format, the programmer provides only * the name of the actual resource. Relative names are * converted to absolute names by the system by prepending * the resource name with the fully qualified package name * of class upon which the <code>getResourceAsStream</code> * method was called. * * @param name name of the desired resource * @return a <code>java.io.InputStream</code> object. */ public java.io.InputStream getResourceAsStream(String name) { throw new Error("getResourceAsStream is not yet implemented!"); // try { // if (name.length() > 0 && name.charAt(0) == '/') { // /* Absolute format */ // name = name.substring(1); // } else { // /* Relative format */ // String className = this.getName(); // int dotIndex = className.lastIndexOf('.'); // if (dotIndex >= 0) { // name = className.substring(0, dotIndex + 1).replace('.', '/') // + name; // } // } // return new com.sun.cldc.io.ResourceInputStream(name); // // } catch (java.io.IOException x) { // return null; // } } /* * This private function is used during virtual machine initialization. * The user does not normally see this function. */ // private static void runCustomCode() {} /* The code below is specific to this VM */ /** * Returns the <code>Class</code> representing the superclass of the entity * (class, interface, primitive type or void) represented by this * <code>Class</code>. If this <code>Class</code> represents either the * <code>Object</code> class, an interface, a primitive type, or void, then * null is returned. If this object represents an array class then the * <code>Class</code> object representing the <code>Object</code> class is * returned. * * Note that this method is not supported by CLDC. * We have made the method private, since it is * needed by our implementation. * * @return the superclass of the class represented by this object. */ // private native Class getSuperclass(); /* * This private variable is used by the VM. * Users never see it. */ // private transient Object vmClass; private int status; private Thread thread; private static final int IN_PROGRESS = 1; private static final int VERIFIED = 2; private static final int INITIALIZED = 4; private static final int ERROR = 8; // Native for invoking <clinit> // private native void invoke_clinit(); /** * Initialization at step 9: * If ENABLE_ISOLATES == false * Remove the <clinit> method after the class is initialized. * If ENABLE_ISOLATES == true, clear class initialization * barrier. */ // private native void init9(); // private native void invoke_verify(); /* * Implements the 11 step program detailed in Java Language Specification * 12.4.2 */ void initialize() throws Throwable { // Step 1 synchronized (this) { // Step 2 while ((status & IN_PROGRESS) != 0 && thread != Thread.currentThread()) { try{ wait(); } catch (InterruptedException e) { } } // Step 3 if ((status & IN_PROGRESS) != 0 && thread == Thread.currentThread()) { return; } // Step 4 if ((status & INITIALIZED) != 0) { return; } // Step 5 if (status == ERROR) { throw new NoClassDefFoundError(getName()); } /* Note: CLDC 1.0 does not have NoClassDefFoundError class */ // Step 6 status |= IN_PROGRESS; thread = Thread.currentThread(); } try { // Step 7 // invoke_verify(); // Class s = getSuperclass(); Class s = null; if (s != null && (s.status & INITIALIZED) == 0) { // The test of s.status is not part of the spec, but // it saves us doing a lot of work in the most common // case. s.initialize(); } // Step 8 // invoke_clinit(); // Step 9 synchronized (this) { status &= ~IN_PROGRESS; status |= INITIALIZED; thread = null; // init9(); notifyAll(); } } catch(Throwable e) { // Step 10 and 11 // CR 6224346, The cldc_vm threading mechanism is such that // we can just jam these values in without fear of another // thread doing the same since only this thread can be // executing the initialize() method and the scheduler is // non-preemptive. We do this here in case the monitorenter // fails due to OOME because some other thread holds the lock, // memory is low and we need to allocate a ConditionDesc to // wait for the lock. status = ERROR; thread = null; synchronized (this) { notifyAll(); throwError(e); } } } private Error throwError(Throwable e) throws Error { throw (e instanceof Error) ? (Error)e : new Error("Static initializer: " + e.getClass().getName() + ", " + e.getMessage()); } }