/* java.lang.Object - The universal superclass in Java
   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004
   Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
 
GNU Classpath 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 for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package java.lang;

/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
 * "The Java Language Specification", ISBN 0-201-63451-1
 * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
 * plus gcj compiler sources (to determine object layout)
 * Status:  Complete to version 1.1
 */

/**
 * Object is the ultimate superclass of every class
 * (excepting interfaces).  When you define a class that
 * does not extend any other class, it implicitly extends
 * java.lang.Object.  Also, an anonymous class based on
 * an interface will extend Object.
 *
 * <p>It provides general-purpose methods that every single
 * Object, regardless of race, sex or creed, implements.
 * All of the public methods may be invoked on arrays or
 * interfaces.  The protected methods <code>clone</code>
 * and <code>finalize</code> are not accessible on arrays
 * or interfaces, but all array types have a public version
 * of <code>clone</code> which is accessible.
 *
 * @author John Keiser
 * @author Eric Blake (ebb9@email.byu.edu)
 * @author Tom Tromey (tromey@cygnus.com)
 */
public class Object
{
  /**
   * Called on an object by the Virtual Machine at most once,
   * at some point after the Object is determined unreachable
   * but before it is destroyed. You would think that this
   * means it eventually is called on every Object, but this is
   * not necessarily the case.  If execution terminates
   * abnormally, garbage collection does not always happen.
   * Thus you cannot rely on this method to always work.
   * For finer control over garbage collection, use references
   * from the {@link java.lang.ref} package.
   *
   * <p>Virtual Machines are free to not call this method if
   * they can determine that it does nothing important; for
   * example, if your class extends Object and overrides
   * finalize to do simply <code>super.finalize()</code>.
   *
   * <p>finalize() will be called by a {@link Thread} that has no
   * locks on any Objects, and may be called concurrently.
   * There are no guarantees on the order in which multiple
   * objects are finalized.  This means that finalize() is
   * usually unsuited for performing actions that must be
   * thread-safe, and that your implementation must be
   * use defensive programming if it is to always work.
   *
   * <p>If an Exception is thrown from finalize() during garbage
   * collection, it will be patently ignored and the Object will
   * still be destroyed.
   *
   * <p>It is allowed, although not typical, for user code to call
   * finalize() directly.  User invocation does not affect whether
   * automatic invocation will occur.  It is also permitted,
   * although not recommended, for a finalize() method to "revive"
   * an object by making it reachable from normal code again.
   *
   * <p>Unlike constructors, finalize() does not get called
   * for an object's superclass unless the implementation
   * specifically calls <code>super.finalize()</code>.
   *
   * <p>The default implementation does nothing.
   *
   * @throws Throwable permits a subclass to throw anything in an
   *         overridden version; but the default throws nothing
   * @see System#gc()
   * @see System#runFinalizersOnExit(boolean)
   * @see java.lang.ref
   */
  // This must come first.  See _JvObjectPrefix in Object.h.
  protected void finalize () throws Throwable
  {
  }

  /**
   * Returns the runtime {@link Class} of this Object.
   *
   * <p>The class object can also be obtained without a runtime
   * instance by using the class literal, as in:
   * <code>Foo.class</code>.  Notice that the class literal
   * also works on primitive types, making it useful for
   * reflection purposes.
   *
   * @return the class of this Object
   */
  public final native Class getClass();

  /**
   * Get a value that represents this Object, as uniquely as
   * possible within the confines of an int.
   *
   * <p>There are some requirements on this method which
   * subclasses must follow:<br>
   *
   * <ul>
   * <li>Semantic equality implies identical hashcodes.  In other
   *     words, if <code>a.equals(b)</code> is true, then
   *     <code>a.hashCode() == b.hashCode()</code> must be as well.
   *     However, the reverse is not necessarily true, and two
   *     objects may have the same hashcode without being equal.</li>
   * <li>It must be consistent.  Whichever value o.hashCode()
   *     returns on the first invocation must be the value
   *     returned on all later invocations as long as the object
   *     exists.  Notice, however, that the result of hashCode may
   *     change between separate executions of a Virtual Machine,
   *     because it is not invoked on the same object.</li>
   * </ul>
   *
   * <p>Notice that since <code>hashCode</code> is used in
   * {@link java.util.Hashtable} and other hashing classes,
   * a poor implementation will degrade the performance of hashing
   * (so don't blindly implement it as returning a constant!). Also,
   * if calculating the hash is time-consuming, a class may consider
   * caching the results.
   *
   * <p>The default implementation returns
   * <code>System.identityHashCode(this)</code>
   *
   * @return the hash code for this Object
   * @see #equals(Object)
   * @see System#identityHashCode(Object)
   */
  public native int hashCode();

  /**
   * Wakes up one of the {@link Thread}s that has called
   * <code>wait</code> on this Object.  Only the owner
   * of a lock on this Object may call this method.  This lock
   * is obtained by a <code>synchronized</code> method or statement.
   *
   * <p>The Thread to wake up is chosen arbitrarily.  The
   * awakened thread is not guaranteed to be the next thread
   * to actually obtain the lock on this object.
   *
   * <p>This thread still holds a lock on the object, so it is
   * typical to release the lock by exiting the synchronized
   * code, calling wait(), or calling {@link Thread#sleep()}, so
   * that the newly awakened thread can actually resume.  The
   * awakened thread will most likely be awakened with an
   * {@link InterruptedException}, but that is not guaranteed.
   *
   * @throws IllegalMonitorStateException if this Thread
   *         does not own the lock on the Object
   * @see #notifyAll()
   * @see #wait()
   * @see #wait(long)
   * @see #wait(long, int)
   * @see Thread
   */
  public final native void notify();
  
  /**
   * Wakes up all of the {@link Thread}s that have called
   * <code>wait</code> on this Object.  Only the owner
   * of a lock on this Object may call this method.  This lock
   * is obtained by a <code>synchronized</code> method or statement.
   *
   * <p>There are no guarantees as to which thread will next
   * obtain the lock on the object.
   *
   * <p>This thread still holds a lock on the object, so it is
   * typical to release the lock by exiting the synchronized
   * code, calling wait(), or calling {@link Thread#sleep()}, so
   * that one of the newly awakened threads can actually resume.
   * The resuming thread will most likely be awakened with an
   * {@link InterruptedException}, but that is not guaranteed.
   *
   * @throws IllegalMonitorStateException if this Thread
   *         does not own the lock on the Object
   * @see #notify()
   * @see #wait()
   * @see #wait(long)
   * @see #wait(long, int)
   * @see Thread
   */
  public final native void notifyAll();

  /**
   * Waits a specified amount of time (or indefinitely if
   * the time specified is 0) for someone to call notify()
   * or notifyAll() on this Object, waking up this Thread.
   *
   * <p>The Thread that calls wait must have a lock on this Object,
   * obtained by a <code>synchronized</code> method or statement.
   * After calling wait, the thread loses the lock on this
   * object until the method completes (abruptly or normally),
   * at which time it regains the lock.  All locks held on
   * other objects remain in force, even though the thread is
   * inactive. Therefore, caution must be used to avoid deadlock.
   *
   * <p>Usually, this call will complete normally if the time
   * expires, or abruptly with {@link InterruptedException}
   * if another thread called notify, but neither result
   * is guaranteed.
   *
   * <p>The waiting period is nowhere near as precise as
   * nanoseconds; considering that even wait(int) is inaccurate,
   * how much can you expect?  But on supporting
   * implementations, this offers somewhat more granularity
   * than milliseconds.
   *
   * @param ms the number of milliseconds to wait (1,000
   *        milliseconds = 1 second)
   * @param ns the number of nanoseconds to wait over and
   *        above ms (1,000,000 nanoseconds = 1 millisecond)
   * @throws IllegalArgumentException if ms &lt; 0 or ns is not
   *         in the range 0 to 999,999
   * @throws IllegalMonitorStateException if this Thread
   *         does not own a lock on this Object
   * @throws InterruptedException if some other Thread
   *         interrupts this Thread
   * @see #notify()
   * @see #notifyAll()
   * @see #wait()
   * @see #wait(long)
   * @see Thread
   */
  public final native void wait(long timeout, int nanos)
    throws InterruptedException;

  /**
   * Determine whether this Object is semantically equal
   * to another Object.
   *
   * <p>There are some fairly strict requirements on this
   * method which subclasses must follow:<br>
   * <ul>
   * <li>It must be transitive.  If <code>a.equals(b)</code> and
   *     <code>b.equals(c)</code>, then <code>a.equals(c)</code>
   *     must be true as well.</li>
   * <li>It must be symmetric.  <code>a.equals(b)</code> and
   *     <code>b.equals(a)</code> must have the same value.</li>
   * <li>It must be reflexive.  <code>a.equals(a)</code> must
   *     always be true.</li>
   * <li>It must be consistent.  Whichever value a.equals(b)
   *     returns on the first invocation must be the value
   *     returned on all later invocations.</li>
   * <li><code>a.equals(null)</code> must be false.</li>
   * <li>It must be consistent with hashCode().  That is,
   *     <code>a.equals(b)</code> must imply
   *     <code>a.hashCode() == b.hashCode()</code>.
   *     The reverse is not true; two objects that are not
   *     equal may have the same hashcode, but that has
   *     the potential to harm hashing performance.</li>
   * </ul>
   *
   * <p>This is typically overridden to throw a {@link ClassCastException}
   * if the argument is not comparable to the class performing
   * the comparison, but that is not a requirement.  It is legal
   * for <code>a.equals(b)</code> to be true even though
   * <code>a.getClass() != b.getClass()</code>.  Also, it
   * is typical to never cause a {@link NullPointerException}.
   *
   * <p>In general, the Collections API ({@link java.util}) use the
   * <code>equals</code> method rather than the <code>==</code>
   * operator to compare objects.  However, {@link java.util.IdentityHashMap}
   * is an exception to this rule, for its own good reasons.
   *
   * <p>The default implementation returns <code>this == o</code>.
   *
   * @param obj the Object to compare to
   * @return whether this Object is semantically equal to another
   * @see #hashCode()
   */
  public boolean equals(Object obj)
  {
    return this == obj;
  }

  /**
   * The basic constructor.  Object is special, because it has no
   * superclass, so there is no call to super().
   *
   * @throws OutOfMemoryError Technically, this constructor never
   *         throws an OutOfMemoryError, because the memory has
   *         already been allocated by this point.  But as all
   *         instance creation expressions eventually trace back
   *         to this constructor, and creating an object allocates
   *         memory, we list that possibility here.
   */
  public Object()
  {
  }

  /**
   * Convert this Object to a human-readable String.
   * There are no limits placed on how long this String
   * should be or what it should contain.  We suggest you
   * make it as intuitive as possible to be able to place
   * it into {@link java.io.PrintStream#println() System.out.println()}
   * and such.
   *
   * <p>It is typical, but not required, to ensure that this method
   * never completes abruptly with a {@link RuntimeException}.
   *
   * <p>This method will be called when performing string
   * concatenation with this object.  If the result is
   * <code>null</code>, string concatenation will instead
   * use <code>"null"</code>.
   *
   * <p>The default implementation returns
   * <code>getClass().getName() + "@" +
   *      Integer.toHexString(hashCode())</code>.
   *
   * @return the String representing this Object, which may be null
   * @throws OutOfMemoryError The default implementation creates a new
   *         String object, therefore it must allocate memory
   * @see #getClass()
   * @see #hashCode()
   * @see Class#getName()
   * @see Integer#toHexString(int)
   */
  public String toString()
  {
    return getClass().getName() + '@' + Integer.toHexString(hashCode());
  }

  /**
   * Waits indefinitely for notify() or notifyAll() to be
   * called on the Object in question.  Implementation is
   * identical to wait(0).
   *
   * <p>The Thread that calls wait must have a lock on this Object,
   * obtained by a <code>synchronized</code> method or statement.
   * After calling wait, the thread loses the lock on this
   * object until the method completes (abruptly or normally),
   * at which time it regains the lock.  All locks held on
   * other objects remain in force, even though the thread is
   * inactive. Therefore, caution must be used to avoid deadlock.
   *
   * <p>While it is typical that this method will complete abruptly
   * with an {@link InterruptedException}, it is not guaranteed.  So,
   * it is typical to call wait inside an infinite loop:<br>
   *
   * <pre>
   * try
   *   {
   *     while (true)
   *       lock.wait();
   *   }
   * catch (InterruptedException e)
   *   {
   *   }
   * </pre>
   *
   * @throws IllegalMonitorStateException if this Thread
   *         does not own a lock on this Object
   * @throws InterruptedException if some other Thread
   *         interrupts this Thread
   * @see #notify()
   * @see #notifyAll()
   * @see #wait(long)
   * @see #wait(long, int)
   * @see Thread
   */
  public final void wait() throws InterruptedException
  {
    wait(0, 0);
  }

  /**
   * Waits a specified amount of time (or indefinitely if
   * the time specified is 0) for someone to call notify()
   * or notifyAll() on this Object, waking up this Thread.
   *
   * <p>The Thread that calls wait must have a lock on this Object,
   * obtained by a <code>synchronized</code> method or statement.
   * After calling wait, the thread loses the lock on this
   * object until the method completes (abruptly or normally),
   * at which time it regains the lock.  All locks held on
   * other objects remain in force, even though the thread is
   * inactive. Therefore, caution must be used to avoid deadlock.
   *
   * <p>Usually, this call will complete normally if the time
   * expires, or abruptly with {@link InterruptedException}
   * if another thread called notify, but neither result
   * is guaranteed.
   *
   * <p>The waiting period is only *roughly* the amount of time
   * you requested.  It cannot be exact because of the overhead
   * of the call itself.  Most Virtual Machiness treat the
   * argument as a lower limit on the time spent waiting, but
   * even that is not guaranteed.  Besides, some other thread
   * may hold the lock on the object when the time expires, so
   * the current thread may still have to wait to reobtain the
   * lock.
   *
   * @param timeout the minimum number of milliseconds to wait (1000
   *        milliseconds = 1 second), or 0 for an indefinite wait
   * @throws IllegalArgumentException if ms &lt; 0
   * @throws IllegalMonitorStateException if this Thread
   *         does not own a lock on this Object
   * @throws InterruptedException if some other Thread
   *         interrupts this Thread
   * @see #notify()
   * @see #notifyAll()
   * @see #wait()
   * @see #wait(long, int)
   * @see Thread
   */
  public final void wait(long timeout) throws InterruptedException
  {
    wait(timeout, 0);
  }

  /**
   * This method may be called to create a new copy of the
   * Object.  The typical behavior is as follows:<br>
   * <ul>
   *  <li><code>o == o.clone()</code> is false</li>
   *  <li><code>o.getClass() == o.clone().getClass()</code>
   *      is true</li>
   *  <li><code>o.equals(o)</code> is true</li>
   * </ul>
   *
   * <p>However, these are not strict requirements, and may
   * be violated if necessary.  Of the three requirements, the
   * last is the most commonly violated, particularly if the
   * subclass does not override {@link #equals(Object)}.
   *
   * <p>If the Object you call clone() on does not implement
   * {@link Cloneable} (which is a placeholder interface), then
   * a CloneNotSupportedException is thrown.  Notice that
   * Object does not implement Cloneable; this method exists
   * as a convenience for subclasses that do.
   *
   * <p>Object's implementation of clone allocates space for the
   * new Object using the correct class, without calling any
   * constructors, and then fills in all of the new field values
   * with the old field values.  Thus, it is a shallow copy.
   * However, subclasses are permitted to make a deep copy.
   *
   * <p>All array types implement Cloneable, and override
   * this method as follows (it should never fail):<br>
   * <pre>
   * public Object clone()
   * {
   *   try
   *     {
   *       super.clone();
   *     }
   *   catch (CloneNotSupportedException e)
   *     {
   *       throw new InternalError(e.getMessage());
   *     }
   * }
   * </pre>
   *
   * @return a copy of the Object
   * @throws CloneNotSupportedException If this Object does not
   *         implement Cloneable
   * @throws OutOfMemoryError Since cloning involves memory allocation,
   *         even though it may bypass constructors, you might run
   *         out of memory
   * @see Cloneable
   */
  protected native Object clone() throws CloneNotSupportedException;

  // This initializes the sync_info member.  It is here for
  // completeness (some day we'll be able to auto-generate Object.h).
  private final native void sync_init();

  // Note that we don't mention the sync_info field here.  If we do,
  // jc1 will not work correctly.
}
