Java的Object对象

时间:2022-11-19 22:47:43

Object对象是除了基础对象之外,所有的对象都需要继承的父对象,包括数组也继承了Object

Object里面的关键函数罗列如下:

clone();调用该函数需要实现 Cloneable,否则会抛出  CloneNotSupportedException的异常。

equals();用来判断两个对象是否相等的函数,默认的是两个对象的地址比较,在使用Compare计算的时候,往往需要重写这个函数。

finalize();这个函数在对象被消解的时候,例如垃圾回收的时候等,会被调用,如果对象使用了不可被自动回收的内存空间等资源,应该在这个函数里面收回。

hashCode();返回的是这个对象的hash值,期内部的实现代码如下:

        int lockWord = shadow$_monitor_;
final int lockWordMask = 0xC0000000; // Top 2 bits.
final int lockWordStateHash = 0x80000000; // Top 2 bits are value 2 (kStateHash).
if ((lockWord & lockWordMask) == lockWordStateHash) {
return lockWord & ~lockWordMask;
}
return System.identityHashCode(this);
& lockWordMask是获取最高两位,
lockWordStateHash是指最高两位是2(10),最高位是符号位,但是不明白为什么要获取两位。
return lockWord & ~lockWordMask; ~是非运算符,所以这句话是返回了除了最高两位的所有其它位的值。

如果不满足上述条件,返回的是
System.identityHashCode(this);,这个是native的方法,没有深入

notify():唤醒被这个对象的monitor标记等待的线程,如果线程的数量大于1,那么被唤醒的线程是由VM自行决定的。注意被唤醒的线程不一定立即执行,至少要等待当前调用notify的线程释放这个对象的monitor,或者等待其他正好同步锁定该对象的线程释放了该对象。 当然了,也不是任何地方都可以调用notify的,调用的地方必须持有对象的monitor,可以有以下几种情况:1.在一个同步( synchronized)方法中;2.在一段该对象的同步代码块中;3.如果这个变量是类变量(static),同步的静态方法也持有。

notifyAll(): 与上面所属的notify类似,只不过是唤醒了所有的线程,当然这些线程也不是立即执行,理由同上。

toString():这个对象的字符串描述,默认的是返回类名和实例的hashCode,代码如下:

    public String toString() {
return getClass().getName() + '@' + Integer.toHexString(hashCode());
}

wait(): 通知当前线程挂起,当对象的notify或者notifyAll被调用的时候才会被重新唤醒,wait了的thread是可以被中断(interrupt)的。当线程wait的时候,这个线程其实丢失了对象的monitor,当被notify的时候,会在程序执行前重新请求到对象的monitor。

还有两个wait函数是带参数的,参数指明了线程的wait时长,如果在这个时长内,线程没有被唤醒,那么当时间到达的时候,这个线程也会被重新唤醒。其他的与上面的wait一致,对了时间为0,说明没有超时时间,时间不可以小于零,否则抛出 IllegalArgumentException

下文中的shadow$_monitor_和shadow$_klass_ 是Android sdk21之后Object增加的两个字段。前者好像是用来表明地址的,后者是用来说明类型的。

Android中的Object源码如下:
/*
* 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.
* @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>
* @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>
* @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>
* @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 { private transient Class<?> shadow$_klass_;
private transient int shadow$_monitor_; // Uncomment the following two fields to enable *s pointers.
// Meant to do "#ifdef USE_*S_POINTER ... #endif" but no macros.
//
// Note names use a 'x' prefix and the _x_rb_ptr_ field is of
// type int instead of Object to go with the alphabetical/by-type
// field order.
// private transient int shadow$_x_rb_ptr_;
// private transient int shadow$_x_xpadding_; /**
* 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 " + getClass().getName() +
" doesn't implement Cloneable");
} return internalClone();
} /*
* Native helper method for cloning.
*/
private native Object internalClone(); /**
* 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;
} /**
* Invoked when the garbage collector has detected that this instance is no longer reachable.
* The default implementation does nothing, but this method can be overridden to free resources.
*
* <p>Note that objects that override {@code finalize} are significantly more expensive than
* objects that don't. Finalizers may be run a long time after the object is no longer
* reachable, depending on memory pressure, so it's a bad idea to rely on them for cleanup.
* Note also that finalizers are run on a single VM-wide finalizer thread,
* so doing blocking work in a finalizer is a bad idea. A finalizer is usually only necessary
* for a class that has a native peer and needs to call a native method to destroy that peer.
* Even then, it's better to provide an explicit {@code close} method (and implement
* {@link java.io.Closeable}), and insist that callers manually dispose of instances. This
* works well for something like files, but less well for something like a {@code BigInteger}
* where typical calling code would have to deal with lots of temporaries. Unfortunately,
* code that creates lots of temporaries is the worst kind of code from the point of view of
* the single finalizer thread.
*
* <p>If you <i>must</i> use finalizers, consider at least providing your own
* {@link java.lang.ref.ReferenceQueue} and having your own thread process that queue.
*
* <p>Unlike constructors, finalizers are not automatically chained. You are responsible for
* calling {@code super.finalize()} yourself.
*
* <p>Uncaught exceptions thrown by finalizers are ignored and do not terminate the finalizer
* thread.
*
* See <i>Effective Java</i> Item 7, "Avoid finalizers" for more.
*/
@FindBugsSuppressWarnings("FI_EMPTY")
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 Class<?> getClass() {
return shadow$_klass_;
} /**
* 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 int hashCode() {
int lockWord = shadow$_monitor_;
final int lockWordMask = 0xC0000000; // Top 2 bits.
final int lockWordStateHash = 0x80000000; // Top 2 bits are value 2 (kStateHash).
if ((lockWord & lockWordMask) == lockWordStateHash) {
return lockWord & ~lockWordMask;
}
return System.identityHashCode(this);
} /**
* 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
* VM. 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
* <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
* <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>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.
*
* @throws IllegalMonitorStateException
* if the thread calling this method is not the owner of this
* object's monitor.
* @throws InterruptedException if the current thread has been interrupted.
* The interrupted status of the current thread will be cleared before the exception
* is thrown.
* @see #notify
* @see #notifyAll
* @see #wait(long)
* @see #wait(long,int)
* @see java.lang.Thread
*/
public final native void wait() throws InterruptedException; /**
* 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>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>A timeout of zero means the calling thread should wait forever unless interrupted or
* notified.
*
* @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 the current thread has been interrupted.
* The interrupted status of the current thread will be cleared before the exception
* is thrown.
* @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>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>A timeout of zero means the calling thread should wait forever unless interrupted or
* notified.
*
* @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 the current thread has been interrupted.
* The interrupted status of the current thread will be cleared before the exception
* is thrown.
* @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;
}