/* java.lang.Object - The universal superclass in Java
   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005
   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., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 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;


/**
 * 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
{
  // WARNING: Object is a CORE class in the bootstrap cycle. See the comments
  // in vm/reference/java/lang/Runtime for implications of this fact.

  // Many JVMs do not allow for static initializers in this class,
  // hence we do not use them in the default implementation.

  // Some VM's rely on the order that these methods appear when laying
  // out their internal structure.  Therefore, do not haphazardly
  // rearrange these methods.

  /**
   * 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.
   */
  // This could be implicit, but then javadoc would not document it!
  public Object() {}

  /**
   * 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;
  }

  /**
   * 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 int hashCode()
  {
    return System.identityHashCode(this);
  }

  /**
   * 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());
  }

  /**
   * 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
   */
  protected void finalize() throws Throwable
  {
  }

  /**
   * 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 Object clone() throws CloneNotSupportedException
  {
    if (this instanceof Cloneable)
      return VMObject.clone((Cloneable) this);
    throw new CloneNotSupportedException("Object not cloneable");
  }

  /**
   * 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 Class getClass()
  {
    return VMObject.getClass(this);
  }

  /**
   * 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(long)}, 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 void notify() throws IllegalMonitorStateException
  {
    VMObject.notify(this);
  }

  /**
   * 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(long)}, 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 void notifyAll() throws IllegalMonitorStateException
  {
    VMObject.notifyAll(this);
  }

  /**
   * 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 IllegalMonitorStateException, InterruptedException
  {
    VMObject.wait(this, 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 ms 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 ms)
    throws IllegalMonitorStateException, InterruptedException
  {
    wait(ms, 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 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 void wait(long ms, int ns)
    throws IllegalMonitorStateException, InterruptedException
  {
    if (ms < 0 || ns < 0 || ns > 999999)
      throw new IllegalArgumentException("argument out of range");
    VMObject.wait(this, ms, ns);
  }
} // class Object
