/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package java.lang;

/**
 * The root class of the Java class hierarchy. All non-primitive types
 * (including arrays) inherit either directly or indirectly from this class.
 *
 * <a name="writing_equals"><h4>Writing a correct {@code equals} method</h4></a>
 * <p>Follow this style to write a canonical {@code equals} method:
 * <pre>
 *   // Use @Override to avoid accidental overloading.
 *   &#x0040;Override public boolean equals(Object o) {
 *     // Return true if the objects are identical.
 *     // (This is just an optimization, not required for correctness.)
 *     if (this == o) {
 *       return true;
 *     }
 *
 *     // Return false if the other object has the wrong type.
 *     // This type may be an interface depending on the interface's specification.
 *     if (!(o instanceof MyType)) {
 *       return false;
 *     }
 *
 *     // Cast to the appropriate type.
 *     // This will succeed because of the instanceof, and lets us access private fields.
 *     MyType lhs = (MyType) o;
 *
 *     // Check each field. Primitive fields, reference fields, and nullable reference
 *     // fields are all treated differently.
 *     return primitiveField == lhs.primitiveField &amp;&amp;
 *             referenceField.equals(lhs.referenceField) &amp;&amp;
 *             (nullableField == null ? lhs.nullableField == null
 *                                    : nullableField.equals(lhs.nullableField));
 *   }
 * </pre>
 * <p>If you override {@code equals}, you should also override {@code hashCode}: equal
 * instances must have equal hash codes.
 *
 * <p>See <i>Effective Java</i> item 8 for much more detail and clarification.
 *
 * <a name="writing_hashCode"><h4>Writing a correct {@code hashCode} method</h4></a>
 * <p>Follow this style to write a canonical {@code hashCode} method:
 * <pre>
 *   &#x0040;Override public int hashCode() {
 *     // Start with a non-zero constant.
 *     int result = 17;
 *
 *     // Include a hash for each field.
 *     result = 31 * result + (booleanField ? 1 : 0);
 *
 *     result = 31 * result + byteField;
 *     result = 31 * result + charField;
 *     result = 31 * result + shortField;
 *     result = 31 * result + intField;
 *
 *     result = 31 * result + (int) (longField ^ (longField >>> 32));
 *
 *     result = 31 * result + Float.floatToIntBits(floatField);
 *
 *     long doubleFieldBits = Double.doubleToLongBits(doubleField);
 *     result = 31 * result + (int) (doubleFieldBits ^ (doubleFieldBits >>> 32));
 *
 *     result = 31 * result + Arrays.hashCode(arrayField);
 *
 *     result = 31 * result + referenceField.hashCode();
 *     result = 31 * result +
 *         (nullableReferenceField == null ? 0
 *                                         : nullableReferenceField.hashCode());
 *
 *     return result;
 *   }
 * </pre>
 *
 * <p>If you don't intend your type to be used as a hash key, don't simply rely on the default
 * {@code hashCode} implementation, because that silently and non-obviously breaks any future
 * code that does use your type as a hash key. You should throw instead:
 * <pre>
 *   &#x0040;Override public int hashCode() {
 *     throw new UnsupportedOperationException();
 *   }
 * </pre>
 *
 * <p>See <i>Effective Java</i> item 9 for much more detail and clarification.
 *
 * <a name="writing_toString"><h4>Writing a useful {@code toString} method</h4></a>
 * <p>For debugging convenience, it's common to override {@code toString} in this style:
 * <pre>
 *   &#x0040;Override public String toString() {
 *     return getClass().getName() + "[" +
 *         "primitiveField=" + primitiveField + ", " +
 *         "referenceField=" + referenceField + ", " +
 *         "arrayField=" + Arrays.toString(arrayField) + "]";
 *   }
 * </pre>
 * <p>The set of fields to include is generally the same as those that would be tested
 * in your {@code equals} implementation.
 * <p>See <i>Effective Java</i> item 10 for much more detail and clarification.
 */
public class Object {
    /**
     * Constructs a new instance of {@code Object}.
     */
    public Object() {
    }

    /**
     * Creates and returns a copy of this {@code Object}. The default
     * implementation returns a so-called "shallow" copy: It creates a new
     * instance of the same class and then copies the field values (including
     * object references) from this instance to the new instance. A "deep" copy,
     * in contrast, would also recursively clone nested objects. A subclass that
     * needs to implement this kind of cloning should call {@code super.clone()}
     * to create the new instance and then create deep copies of the nested,
     * mutable objects.
     *
     * @return a copy of this object.
     * @throws CloneNotSupportedException
     *             if this object's class does not implement the {@code
     *             Cloneable} interface.
     */
    protected Object clone() throws CloneNotSupportedException {
        if (!(this instanceof Cloneable)) {
            throw new CloneNotSupportedException("Class doesn't implement Cloneable");
        }

        return internalClone((Cloneable) this);
    }

    /*
     * Native helper method for cloning.
     */
    private native Object internalClone(Cloneable o);

    /**
     * Compares this instance with the specified object and indicates if they
     * are equal. In order to be equal, {@code o} must represent the same object
     * as this instance using a class-specific comparison. The general contract
     * is that this comparison should be reflexive, symmetric, and transitive.
     * Also, no object reference other than null is equal to null.
     *
     * <p>The default implementation returns {@code true} only if {@code this ==
     * o}. See <a href="{@docRoot}/reference/java/lang/Object.html#writing_equals">Writing a correct {@code equals} method</a>
     * if you intend implementing your own {@code equals} method.
     *
     * <p>The general contract for the {@code equals} and {@link
     * #hashCode()} methods is that if {@code equals} returns {@code true} for
     * any two objects, then {@code hashCode()} must return the same value for
     * these objects. This means that subclasses of {@code Object} usually
     * override either both methods or neither of them.
     *
     * @param o
     *            the object to compare this instance with.
     * @return {@code true} if the specified object is equal to this {@code
     *         Object}; {@code false} otherwise.
     * @see #hashCode
     */
    public boolean equals(Object o) {
        return this == o;
    }

    /**
     * Called before the object's memory is reclaimed by the VM. This
     * can only happen once the garbage collector has detected that the
     * object is no longer reachable by any thread of the
     * running application.
     * <p>
     * The method can be used to free system resources or perform other cleanup
     * before the object is garbage collected. The default implementation of the
     * method is empty, which is also expected by the VM, but subclasses can
     * override {@code finalize()} as required. Uncaught exceptions which are
     * thrown during the execution of this method cause it to terminate
     * immediately but are otherwise ignored.
     * <p>
     * Note that the VM does guarantee that {@code finalize()} is called at most
     * once for any object, but it doesn't guarantee when (if at all) {@code
     * finalize()} will be called. For example, object B's {@code finalize()}
     * can delay the execution of object A's {@code finalize()} method and
     * therefore it can delay the reclamation of A's memory. To be safe, use a
     * {@link java.lang.ref.ReferenceQueue}, because it provides more control
     * over the way the VM deals with references during garbage collection.
     * </p>
     *
     * @throws Throwable
     *             any exception which is raised during finalization; these are
     *             ignored by the virtual machine.
     */
    protected void finalize() throws Throwable {
    }

    /**
     * Returns the unique instance of {@link Class} that represents this
     * object's class. Note that {@code getClass()} is a special case in that it
     * actually returns {@code Class<? extends Foo>} where {@code Foo} is the
     * erasure of the type of the expression {@code getClass()} was called upon.
     * <p>
     * As an example, the following code actually compiles, although one might
     * think it shouldn't:
     * <p>
     * <pre>{@code
     *   List<Integer> l = new ArrayList<Integer>();
     *   Class<? extends List> c = l.getClass();}</pre>
     *
     * @return this object's {@code Class} instance.
     */
    public final native Class<? extends Object> getClass();

    /**
     * Returns an integer hash code for this object. By contract, any two
     * objects for which {@link #equals} returns {@code true} must return
     * the same hash code value. This means that subclasses of {@code Object}
     * usually override both methods or neither method.
     *
     * <p>Note that hash values must not change over time unless information used in equals
     * comparisons also changes.
     *
     * <p>See <a href="{@docRoot}/reference/java/lang/Object.html#writing_hashCode">Writing a correct {@code hashCode} method</a>
     * if you intend implementing your own {@code hashCode} method.
     *
     * @return this object's hash code.
     * @see #equals
     */
    public native int hashCode();

    /**
     * Causes a thread which is waiting on this object's monitor (by means of
     * calling one of the {@code wait()} methods) to be woken up. If more than
     * one thread is waiting, one of them is chosen at the discretion of the
     * virtual machine. The chosen thread will not run immediately. The thread
     * that called {@code notify()} has to release the object's monitor first.
     * Also, the chosen thread still has to compete against other threads that
     * try to synchronize on the same object.
     * <p>
     * This method can only be invoked by a thread which owns this object's
     * monitor. A thread becomes owner of an object's monitor
     * </p>
     * <ul>
     * <li>by executing a synchronized method of that object;</li>
     * <li>by executing the body of a {@code synchronized} statement that
     * synchronizes on the object;</li>
     * <li>by executing a synchronized static method if the object is of type
     * {@code Class}.</li>
     * </ul>
     *
     * @see #notifyAll
     * @see #wait()
     * @see #wait(long)
     * @see #wait(long,int)
     * @see java.lang.Thread
     */
    public final native void notify();

    /**
     * Causes all threads which are waiting on this object's monitor (by means
     * of calling one of the {@code wait()} methods) to be woken up. The threads
     * will not run immediately. The thread that called {@code notify()} has to
     * release the object's monitor first. Also, the threads still have to
     * compete against other threads that try to synchronize on the same object.
     * <p>
     * This method can only be invoked by a thread which owns this object's
     * monitor. A thread becomes owner of an object's monitor
     * </p>
     * <ul>
     * <li>by executing a synchronized method of that object;</li>
     * <li>by executing the body of a {@code synchronized} statement that
     * synchronizes on the object;</li>
     * <li>by executing a synchronized static method if the object is of type
     * {@code Class}.</li>
     * </ul>
     *
     * @throws IllegalMonitorStateException
     *             if the thread calling this method is not the owner of this
     *             object's monitor.
     * @see #notify
     * @see #wait()
     * @see #wait(long)
     * @see #wait(long,int)
     * @see java.lang.Thread
     */
    public final native void notifyAll();

    /**
     * Returns a string containing a concise, human-readable description of this
     * object. Subclasses are encouraged to override this method and provide an
     * implementation that takes into account the object's type and data. The
     * default implementation is equivalent to the following expression:
     * <pre>
     *   getClass().getName() + '@' + Integer.toHexString(hashCode())</pre>
     * <p>See <a href="{@docRoot}/reference/java/lang/Object.html#writing_toString">Writing a useful {@code toString} method</a>
     * if you intend implementing your own {@code toString} method.
     *
     * @return a printable representation of this object.
     */
    public String toString() {
        return getClass().getName() + '@' + Integer.toHexString(hashCode());
    }

    /**
     * Causes the calling thread to wait until another thread calls the {@code
     * notify()} or {@code notifyAll()} method of this object. This method can
     * only be invoked by a thread which owns this object's monitor; see
     * {@link #notify()} on how a thread can become the owner of a monitor.
     * <p>
     * A waiting thread can be sent {@code interrupt()} to cause it to
     * prematurely stop waiting, so {@code wait} should be called in a loop to
     * check that the condition that has been waited for has been met before
     * continuing.
     * </p>
     * <p>
     * While the thread waits, it gives up ownership of this object's monitor.
     * When it is notified (or interrupted), it re-acquires the monitor before
     * it starts running.
     * </p>
     *
     * @throws IllegalMonitorStateException
     *             if the thread calling this method is not the owner of this
     *             object's monitor.
     * @throws InterruptedException
     *             if another thread interrupts this thread while it is waiting.
     * @see #notify
     * @see #notifyAll
     * @see #wait(long)
     * @see #wait(long,int)
     * @see java.lang.Thread
     */
    public final void wait() throws InterruptedException {
        wait(0 ,0);
    }

    /**
     * Causes the calling thread to wait until another thread calls the {@code
     * notify()} or {@code notifyAll()} method of this object or until the
     * specified timeout expires. This method can only be invoked by a thread
     * which owns this object's monitor; see {@link #notify()} on how a thread
     * can become the owner of a monitor.
     * <p>
     * A waiting thread can be sent {@code interrupt()} to cause it to
     * prematurely stop waiting, so {@code wait} should be called in a loop to
     * check that the condition that has been waited for has been met before
     * continuing.
     * </p>
     * <p>
     * While the thread waits, it gives up ownership of this object's monitor.
     * When it is notified (or interrupted), it re-acquires the monitor before
     * it starts running.
     * </p>
     *
     * @param millis
     *            the maximum time to wait in milliseconds.
     * @throws IllegalArgumentException
     *             if {@code millis < 0}.
     * @throws IllegalMonitorStateException
     *             if the thread calling this method is not the owner of this
     *             object's monitor.
     * @throws InterruptedException
     *             if another thread interrupts this thread while it is waiting.
     * @see #notify
     * @see #notifyAll
     * @see #wait()
     * @see #wait(long,int)
     * @see java.lang.Thread
     */
    public final void wait(long millis) throws InterruptedException {
        wait(millis, 0);
    }

    /**
     * Causes the calling thread to wait until another thread calls the {@code
     * notify()} or {@code notifyAll()} method of this object or until the
     * specified timeout expires. This method can only be invoked by a thread
     * that owns this object's monitor; see {@link #notify()} on how a thread
     * can become the owner of a monitor.
     * <p>
     * A waiting thread can be sent {@code interrupt()} to cause it to
     * prematurely stop waiting, so {@code wait} should be called in a loop to
     * check that the condition that has been waited for has been met before
     * continuing.
     * </p>
     * <p>
     * While the thread waits, it gives up ownership of this object's monitor.
     * When it is notified (or interrupted), it re-acquires the monitor before
     * it starts running.
     * </p>
     *
     * @param millis
     *            the maximum time to wait in milliseconds.
     * @param nanos
     *            the fraction of a millisecond to wait, specified in
     *            nanoseconds.
     * @throws IllegalArgumentException
     *             if {@code millis < 0}, {@code nanos < 0} or {@code nanos >
     *             999999}.
     * @throws IllegalMonitorStateException
     *             if the thread calling this method is not the owner of this
     *             object's monitor.
     * @throws InterruptedException
     *             if another thread interrupts this thread while it is waiting.
     * @see #notify
     * @see #notifyAll
     * @see #wait()
     * @see #wait(long,int)
     * @see java.lang.Thread
     */
    public final native void wait(long millis, int nanos) throws InterruptedException;
}
