001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026:
027: package java.lang;
028:
029: /**
030: * Instances of the class <code>Class</code> represent classes and interfaces
031: * in a running Java application. Every array also belongs to a class that is
032: * reflected as a <code>Class</code> object that is shared by all arrays with
033: * the same element type and number of dimensions.
034: *
035: * <p> <code>Class</code> has no public constructor. Instead <code>Class</code>
036: * objects are constructed automatically by the Java Virtual Machine as classes
037: * are loaded.
038: *
039: * <p> The following example uses a <code>Class</code> object to print the
040: * class name of an object:
041: *
042: * <p> <blockquote><pre>
043: * void printClassName(Object obj) {
044: * System.out.println("The class of " + obj +
045: * " is " + obj.getClass().getName());
046: * }
047: * </pre></blockquote>
048: *
049: * @version 12/17/01 (CLDC 1.1)
050: * @since JDK1.0, CLDC 1.0
051: */
052: public final class Class {
053:
054: /*
055: * Constructor. Only the Java Virtual Machine creates Class
056: * objects.
057: */
058: private Class() {
059: }
060:
061: /**
062: * Converts the object to a string. The string representation is the
063: * string "class" or "interface", followed by a space, and then by the
064: * fully qualified name of the class in the format returned by
065: * <code>getName</code>. If this <code>Class</code> object represents a
066: * primitive type, this method returns the name of the primitive type. If
067: * this <code>Class</code> object represents void this method returns
068: * "void".
069: *
070: * @return a string representation of this class object.
071: */
072: public String toString() {
073: return (isInterface() ? "interface " : "class ") + getName();
074: }
075:
076: /**
077: * Returns the <code>Class</code> object associated with the class
078: * with the given string name. Given the fully-qualified name for
079: * a class or interface, this method attempts to locate, load and
080: * link the class.
081: * <p>
082: * For example, the following code fragment returns the runtime
083: * <code>Class</code> descriptor for the class named
084: * <code>java.lang.Thread</code>:
085: * <ul><code>
086: * Class t = Class.forName("java.lang.Thread")
087: * </code></ul>
088: *
089: * @param className the fully qualified name of the desired class.
090: * @return the <code>Class</code> object for the class with the
091: * specified name.
092: * @exception ClassNotFoundException if the class could not be found.
093: * @exception Error if the function fails for any other reason.
094: * @since JDK1.0
095: */
096: public static native Class forName(String className)
097: throws ClassNotFoundException;
098:
099: /**
100: * Creates a new instance of a class.
101: *
102: * @return a newly allocated instance of the class represented by this
103: * object. This is done exactly as if by a <code>new</code>
104: * expression with an empty argument list.
105: * @exception IllegalAccessException if the class or initializer is
106: * not accessible.
107: * @exception InstantiationException if an application tries to
108: * instantiate an abstract class or an interface, or if the
109: * instantiation fails for some other reason.
110: * @since JDK1.0
111: */
112: public native Object newInstance() throws InstantiationException,
113: IllegalAccessException;
114:
115: /**
116: * Determines if the specified <code>Object</code> is assignment-compatible
117: * with the object represented by this <code>Class</code>. This method is
118: * the dynamic equivalent of the Java language <code>instanceof</code>
119: * operator. The method returns <code>true</code> if the specified
120: * <code>Object</code> argument is non-null and can be cast to the
121: * reference type represented by this <code>Class</code> object without
122: * raising a <code>ClassCastException.</code> It returns <code>false</code>
123: * otherwise.
124: *
125: * <p> Specifically, if this <code>Class</code> object represents a
126: * declared class, this method returns <code>true</code> if the specified
127: * <code>Object</code> argument is an instance of the represented class (or
128: * of any of its subclasses); it returns <code>false</code> otherwise. If
129: * this <code>Class</code> object represents an array class, this method
130: * returns <code>true</code> if the specified <code>Object</code> argument
131: * can be converted to an object of the array class by an identity
132: * conversion or by a widening reference conversion; it returns
133: * <code>false</code> otherwise. If this <code>Class</code> object
134: * represents an interface, this method returns <code>true</code> if the
135: * class or any superclass of the specified <code>Object</code> argument
136: * implements this interface; it returns <code>false</code> otherwise. If
137: * this <code>Class</code> object represents a primitive type, this method
138: * returns <code>false</code>.
139: *
140: * @param obj the object to check
141: * @return true if <code>obj</code> is an instance of this class
142: *
143: * @since JDK1.1
144: */
145: public native boolean isInstance(Object obj);
146:
147: /**
148: * Determines if the class or interface represented by this
149: * <code>Class</code> object is either the same as, or is a superclass or
150: * superinterface of, the class or interface represented by the specified
151: * <code>Class</code> parameter. It returns <code>true</code> if so;
152: * otherwise it returns <code>false</code>. If this <code>Class</code>
153: * object represents a primitive type, this method returns
154: * <code>true</code> if the specified <code>Class</code> parameter is
155: * exactly this <code>Class</code> object; otherwise it returns
156: * <code>false</code>.
157: *
158: * <p> Specifically, this method tests whether the type represented by the
159: * specified <code>Class</code> parameter can be converted to the type
160: * represented by this <code>Class</code> object via an identity conversion
161: * or via a widening reference conversion. See <em>The Java Language
162: * Specification</em>, sections 5.1.1 and 5.1.4 , for details.
163: *
164: * @param cls the <code>Class</code> object to be checked
165: * @return the <code>boolean</code> value indicating whether objects of the
166: * type <code>cls</code> can be assigned to objects of this class
167: * @exception NullPointerException if the specified Class parameter is
168: * null.
169: * @since JDK1.1
170: */
171: public native boolean isAssignableFrom(Class cls);
172:
173: /**
174: * Determines if the specified <code>Class</code> object represents an
175: * interface type.
176: *
177: * @return <code>true</code> if this object represents an interface;
178: * <code>false</code> otherwise.
179: */
180: public native boolean isInterface();
181:
182: /**
183: * Determines if this <code>Class</code> object represents an array class.
184: *
185: * @return <code>true</code> if this object represents an array class;
186: * <code>false</code> otherwise.
187: * @since JDK1.1
188: */
189: public native boolean isArray();
190:
191: /**
192: * Returns the fully-qualified name of the entity (class, interface, array
193: * class, primitive type, or void) represented by this <code>Class</code>
194: * object, as a <code>String</code>.
195: *
196: * <p> If this <code>Class</code> object represents a class of arrays, then
197: * the internal form of the name consists of the name of the element type
198: * in Java signature format, preceded by one or more "<tt>[</tt>"
199: * characters representing the depth of array nesting. Thus:
200: *
201: * <blockquote><pre>
202: * (new Object[3]).getClass().getName()
203: * </pre></blockquote>
204: *
205: * returns "<code>[Ljava.lang.Object;</code>" and:
206: *
207: * <blockquote><pre>
208: * (new int[3][4][5][6][7][8][9]).getClass().getName()
209: * </pre></blockquote>
210: *
211: * returns "<code>[[[[[[[I</code>". The encoding of element type names
212: * is as follows:
213: *
214: * <blockquote><pre>
215: * B byte
216: * C char
217: * D double
218: * F float
219: * I int
220: * J long
221: * L<i>classname;</i> class or interface
222: * S short
223: * Z boolean
224: * </pre></blockquote>
225: *
226: * The class or interface name <tt><i>classname</i></tt> is given in fully
227: * qualified form as shown in the example above.
228: *
229: * @return the fully qualified name of the class or interface
230: * represented by this object.
231: */
232: public native String getName();
233:
234: /**
235: * Finds a resource with a given name in the application's
236: * JAR file. This method returns
237: * <code>null</code> if no resource with this name is found
238: * in the application's JAR file.
239: * <p>
240: * The resource names can be represented in two
241: * different formats: absolute or relative.
242: * <p>
243: * Absolute format:
244: * <ul><code>/packagePathName/resourceName</code></ul>
245: * <p>
246: * Relative format:
247: * <ul><code>resourceName</code></ul>
248: * <p>
249: * In the absolute format, the programmer provides a fully
250: * qualified name that includes both the full path and the
251: * name of the resource inside the JAR file. In the path names,
252: * the character "/" is used as the separator.
253: * <p>
254: * In the relative format, the programmer provides only
255: * the name of the actual resource. Relative names are
256: * converted to absolute names by the system by prepending
257: * the resource name with the fully qualified package name
258: * of class upon which the <code>getResourceAsStream</code>
259: * method was called.
260: *
261: * @param name name of the desired resource
262: * @return a <code>java.io.InputStream</code> object.
263: */
264: public java.io.InputStream getResourceAsStream(String name) {
265: try {
266: if (name.length() > 0 && name.charAt(0) == '/') {
267: /* Absolute format */
268: name = name.substring(1);
269: } else {
270: /* Relative format */
271: String className = this .getName();
272: int dotIndex = className.lastIndexOf('.');
273: if (dotIndex >= 0) {
274: name = className.substring(0, dotIndex + 1)
275: .replace('.', '/')
276: + name;
277: }
278: }
279: return new com.sun.cldc.io.ResourceInputStream(name);
280: } catch (java.io.IOException x) {
281: return null;
282: }
283: }
284:
285: /*
286: * This private function is used during virtual machine initialization.
287: * The user does not normally see this function.
288: */
289: // private static void runCustomCode() {}
290: /* The code below is specific to this VM */
291:
292: /**
293: * Returns the <code>Class</code> representing the superclass of the entity
294: * (class, interface, primitive type or void) represented by this
295: * <code>Class</code>. If this <code>Class</code> represents either the
296: * <code>Object</code> class, an interface, a primitive type, or void, then
297: * null is returned. If this object represents an array class then the
298: * <code>Class</code> object representing the <code>Object</code> class is
299: * returned.
300: *
301: * Note that this method is not supported by CLDC.
302: * We have made the method private, since it is
303: * needed by our implementation.
304: *
305: * @return the superclass of the class represented by this object.
306: */
307: private native Class getSuperclass();
308:
309: /*
310: * This private variable is used by the VM.
311: * Users never see it.
312: */
313: private transient Object vmClass;
314:
315: private int status;
316: private Thread thread;
317:
318: private static final int IN_PROGRESS = 1;
319: private static final int VERIFIED = 2;
320: private static final int INITIALIZED = 4;
321: private static final int ERROR = 8;
322:
323: // Native for invoking <clinit>
324: private native void invoke_clinit();
325:
326: /**
327: * Initialization at step 9:
328: * If ENABLE_ISOLATES == false
329: * Remove the <clinit> method after the class is initialized.
330: * If ENABLE_ISOLATES == true, clear class initialization
331: * barrier.
332: */
333: private native void init9();
334:
335: private native void invoke_verify();
336:
337: /*
338: * Implements the 11 step program detailed in Java Language Specification
339: * 12.4.2
340: */
341: void initialize() throws Throwable {
342: // Step 1
343: synchronized (this ) {
344: // Step 2
345: while ((status & IN_PROGRESS) != 0
346: && thread != Thread.currentThread()) {
347: try {
348: wait();
349: } catch (InterruptedException e) {
350: }
351: }
352:
353: // Step 3
354: if ((status & IN_PROGRESS) != 0
355: && thread == Thread.currentThread()) {
356: return;
357: }
358:
359: // Step 4
360: if ((status & INITIALIZED) != 0) {
361: return;
362: }
363:
364: // Step 5
365: if (status == ERROR) {
366: throw new NoClassDefFoundError(getName());
367: }
368: /* Note: CLDC 1.0 does not have NoClassDefFoundError class */
369:
370: // Step 6
371: status |= IN_PROGRESS;
372: thread = Thread.currentThread();
373: }
374:
375: try {
376: // Step 7
377: invoke_verify();
378: Class s = getSuperclass();
379: if (s != null && (s.status & INITIALIZED) == 0) {
380: // The test of s.status is not part of the spec, but
381: // it saves us doing a lot of work in the most common
382: // case.
383: s.initialize();
384: }
385:
386: // Step 8
387: invoke_clinit();
388:
389: // Step 9
390: synchronized (this ) {
391: status &= ~IN_PROGRESS;
392: status |= INITIALIZED;
393: thread = null;
394: init9();
395: notifyAll();
396: }
397: } catch (Throwable e) {
398: // Step 10 and 11
399: // CR 6224346, The cldc_vm threading mechanism is such that
400: // we can just jam these values in without fear of another
401: // thread doing the same since only this thread can be
402: // executing the initialize() method and the scheduler is
403: // non-preemptive. We do this here in case the monitorenter
404: // fails due to OOME because some other thread holds the lock,
405: // memory is low and we need to allocate a ConditionDesc to
406: // wait for the lock.
407: status = ERROR;
408: thread = null;
409: synchronized (this ) {
410: notifyAll();
411: throwError(e);
412: }
413: }
414: }
415:
416: private Error throwError(Throwable e) throws Error {
417: throw (e instanceof Error) ? (Error) e : new Error(
418: "Static initializer: " + e.getClass().getName() + ", "
419: + e.getMessage());
420: }
421: }
|