/* 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<? extends Object> 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
