点赞再看,养成习惯,公众号搜一搜【一角钱技术】关注更多原创技术文章。本文 GitHub org_hejianhui/JavaStudy 已收录,有个人系列文章。java
Java 是一门面向对象的语言,在 Java 里面一切均可以看做是一个对象,而 Java 里面全部的对象都默认继承于 Object 类。git
本文基于JDK1.8程序员
能够看到一共12个方法,其中 registerNatives() 是 native 修饰的,一个本地方法,具体是用C(C++)在DLL中实现的,而后经过JNI调用。github
public final native Class<?> getClass();
复制代码
getClass 也是个 native 方法,这个方法的做用就是返回某个对象的运行时类,它的返回值是 Class 类型,Class c = obj.getClass();经过对象 c ,咱们能够获取该对象的全部成员方法,每一个成员方法都是一个 Method 对象;咱们也能够获取该对象的全部成员变量,每一个成员变量都是一个 Field 对象;一样的,咱们也能够获取该对象的构造函数,构造函数则是一个 Constructor 对象。这个方法在反射时会经常使用到。web
public native int hashCode();
复制代码
public boolean equals(Object obj) {
return (this == obj);
}
复制代码
equals 的实现很是简单,它的做用就是比较两个对象是否相等,而比较的依据就是两者的内存地址。除此以外,equals 还遵循如下几个原则:编程
1、自反性:x.equals(x); // true
2、对称性:x.equals(y) == y.equals(x); // true
3、传递性:if (x.equals(y) && y.equals(z))
x.equals(z); // true;
4、一致性,只要对象没有被修改,屡次调用 equals() 方法结果不变:
x.equals(y) == x.equals(y); // true
5、非空性,对任何不是 null 的对象 x 调用 x.equals(null) 结果都为 false :
x.equals(null); // false;
复制代码
由于这两个方法都跟对象的比较有关,因此若是在程序中要作对象比较,那大几率要重写这两个方法了。由于equals默认的比较逻辑就是对象的地址进行比较,两个对象内存地址确定不一样,因此不管如何两个对象经过eqals比较确定返回false。markdown
但在实际编程中,咱们常常会遇到去重,或者将对象放到有序集合中,或者将对象存入无重复的集合中,这时若是没有重写equals和hashCode,则没法达到需求。svg
举个例子,系统中同时存在两个对象,对象A和对象B,其姓名和身份证号如出一辙。此时,在系统内存中是两个对象,但其内容一致分明是一我的同时产生了两条重复信息。若是使用默认的equals方法比较,则这两个对象永远不相等,永远不能比出来是一条相同的重复信息。因此,要重写equals和hashCode方法来达到以上需求效果。函数
protected native Object clone() throws CloneNotSupportedException;
复制代码
clone() 是 Object 的 protected 方法,它不是 public,一个类不显式去重写 clone(),其它类就不能直接去调用该类实例的 clone() 方法。此外,Clone 的注释中还提到比较重要的几点:oop
关于浅拷贝与深拷贝咱们后面再讨论。
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
复制代码
返回该对象的字符串表示,很是重要的方法
public final void wait() throws InterruptedException {
wait(0);
}
public final native void wait(long timeout) throws InterruptedException;
public final void wait(long timeout, int nanos) throws InterruptedException {
if (timeout < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (nanos < 0 || nanos > 999999) {
throw new IllegalArgumentException(
"nanosecond timeout value out of range");
}
if (nanos > 0) {
timeout++;
}
wait(timeout);
}
复制代码
wait 的做用是让当前线程进入等待状态,同时,wait() 也会让当前线程释放它所持有的锁。直到其余线程调用此对象的 notify() 方法或 notifyAll() 方法,当前线程被唤醒进入就绪状态。
wait(long timeout) (以毫秒为单位)让当前线程处于等待(阻塞)状态,直到其余线程调用此对象的notify() 方法或 notifyAll() 方法,或者超过指定的时间量,当前线程被唤醒进入就绪状态。
wait(long timeout, int nanos) 和 wait(long timeout) 功能同样,惟一的区别是这个能够提供更高的精度。总超时时间(以纳秒为单位)计算为 1000000 *timeout+ nanos。By the way ,wait(0,0) 和 wait(0) 效果同样。
public final native void notify();
public final native void notifyAll();
复制代码
首先是 notify ,notify 的做用就是随机唤醒在等待队列的某个线程,而 notifyAll 就是唤醒在等待队列的全部线程。
注意:notify 和 wait 方法的使用规范。意思就是这两者必须在 synchronized 修饰的同步方法或同步代码中使用。
首先,两者均可以暂停当前线程,释放 CPU 控制权。主要的区别在于 Object.wait()在释放 CPU 同时,释放了对象锁的控制。而 Thread.sleep() 没有对锁释放。换句话说 sleep 就是耍流氓,占着茅坑不拉屎。
package java.lang;
public class Object {
/** * 一个本地方法,具体是用C(C++)在DLL中实现的,而后经过JNI调用 */
private static native void registerNatives();
/** * 对象初始化时自动调用此方法 */
static {
registerNatives();
}
/** * 返回此Object的运行时类 */
public final native Class<?> getClass();
/** * hashCode的常规协定是: * 1.在java应用程序执行期间,在对同一对象屡次调用hashCode()方法时,必须一致地返回相同的整数,前提是将对象进行equals比较时所用的信息没有被修改。 * 从某一应用程序的一次执行到同一应用程序的另外一次执行,该整数无需保持一致。 * 2.若是根据equals(object)方法,两个对象是相等的,那么对这两个对象中的每一个对象调用hashCode方法都必须生成相同的整数结果。 * 3.若是根据equals(java.lang.Object)方法,两个对象不相等,那么对这两个对象中的任一对象上调用hashCode()方法不要求必定生成不一样的整数结果。 * 可是,程序员应该意识到,为不相等的对象生成不一样整数结果能够提升哈希表的性能。 */
public native int hashCode();
/** * 这里比较的是对象的内存地址 */
public boolean equals(Object obj) {
return (this == obj);
}
/** * 本地clone方法,用于对象的复制 */
protected native Object clone() throws CloneNotSupportedException;
/** * 返回该对象的字符串表示,很是重要的方法 * getClass().getName();获取字节码文件的对应全路径名例如java.lang.Object * Integer.toHexString(hashCode());将哈希值转成16进制数格式的字符串。 */
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
/** * 不能被重写,用于唤醒一个在因等待该对象(调用了wait方法)被处于等待状态(waiting 或 time_wait)的线程,该方法只能同步方法或同步块中调用 */
public final native void notify();
/** * 不能被重写,用于唤醒全部在因等待该对象(调用wait方法)被处于等待状态(waiting或time_waiting)的线程,该方法只能同步方法或同步块中调用 */
public final native void notifyAll();
/** * 不能被重写,用于在线程调用中,致使当前线程进入等待状态(time_waiting),timeout单位为毫秒,该方法只能同步方法或同步块中调用,超过设置时间后线程从新进入可运行状态 */
public final native void wait(long timeout) throws InterruptedException;
public final void wait(long timeout, int nanos) throws InterruptedException {
if (timeout < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (nanos < 0 || nanos > 999999) {
throw new IllegalArgumentException(
"nanosecond timeout value out of range");
}
if (nanos > 0) {
timeout++;
}
wait(timeout);
}
/** * 在其余线程调用此对象的notify()方法或notifyAll()方法前,致使当前线程等待。换句话说,此方法的行为就好像它仅执行wait(0)调用同样。 * 当前线程必须拥有此对象监视器。 * 该线程发布对此监视器的全部权并等待,直到其余线程经过调用notify方法或notifyAll方法通知在此对象的监视器上等待的线程醒来, * 而后该线程将等到从新得到对监视器的全部权后才能继续执行。 */
public final void wait() throws InterruptedException {
wait(0);
}
/** * 这个方法用于当对象被回收时调用,这个由JVM支持,Object的finalize方法默认是什么都没有作,若是子类须要在对象被回收时执行一些逻辑处理,则能够重写finalize方法。 */
protected void finalize() throws Throwable {
}
}
复制代码
PS:这里有一个技术交流群(扣扣群:1158819530),方便你们一块儿交流,持续学习,共同进步,有须要的能够加一下。
文章持续更新,能够公众号搜一搜「 一角钱技术 」第一时间阅读, 本文 GitHub org_hejianhui/JavaStudy 已经收录,欢迎 Star。