千家信息网

Java基础之如何理解Object源码

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,本篇内容主要讲解"Java基础之如何理解Object源码",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Java基础之如何理解Object源码"吧!getC
千家信息网最后更新 2026年11月03日Java基础之如何理解Object源码

本篇内容主要讲解"Java基础之如何理解Object源码",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Java基础之如何理解Object源码"吧!

getClass

public final native Class getClass();

getClass 也是个 native 方法,这个方法的作用就是返回某个对象的运行时类,它的返回值是 Class 类型,Class c = obj.getClass();通过对象 c ,我们可以获取该对象的所有成员方法,每个成员方法都是一个 Method 对象;我们也可以获取该对象的所有成员变量,每个成员变量都是一个 Field 对象;同样的,我们也可以获取该对象的构造函数,构造函数则是一个 Constructor 对象。这个方法在反射时会常用到。

hashCode

public native int hashCode();
  • hashCode 方法返回散列值。

  • 返回值默认是由对象的地址转换而来的。

  • 同一个对象调用 hashCode 的返回值是相等的。

  • 两个对象的 equals 相等,那 hashCode 一定相等。

  • 两个对象的 equals 不相等,那 hashCode 也不一定相等。

equals

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;

为什么要重写 hashcode 和 equals ?

因为这两个方法都跟对象的比较有关,所以如果在程序中要做对象比较,那大概率要重写这两个方法了。因为equals默认的比较逻辑就是对象的地址进行比较,两个对象内存地址肯定不同,所以无论如何两个对象通过eqals比较肯定返回false。

但在实际编程中,我们经常会遇到去重,或者将对象放到有序集合中,或者将对象存入无重复的集合中,这时如果没有重写equals和hashCode,则无法达到需求。

举个例子,系统中同时存在两个对象,对象A和对象B,其姓名和身份证号一模一样。此时,在系统内存中是两个对象,但其内容一致分明是一个人同时产生了两条重复信息。如果使用默认的equals方法比较,则这两个对象永远不相等,永远不能比出来是一条相同的重复信息。所以,要重写equals和hashCode方法来达到以上需求效果。

clone

protected native Object clone() throws CloneNotSupportedException;

clone() 是 Object 的 protected 方法,它不是 public,一个类不显式去重写 clone(),其它类就不能直接去调用该类实例的 clone() 方法。此外,Clone 的注释中还提到比较重要的几点:

  • 克隆的对象必须要实现 Cloneable 接口并重写 clone 方法,否则会报 CloneNotSupportedException 异常

  • clone() 方法并不是 Cloneable 接口的方法,而是 Object 的一个 protected 方法。Cloneable 接口只是规定,如果一个类没有实现 Cloneable 接口又调用了 clone() 方法,就会抛出 CloneNotSupportedException。

  • 浅拷贝:拷贝对象和原始对象的引用类型引用同一个对象。

  • 深拷贝:拷贝对象和原始对象的引用类型引用不同对象。

关于浅拷贝与深拷贝我们后面再讨论。

toString

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

返回该对象的字符串表示,非常重要的方法

  • getClass().getName(); 获取字节码文件的对应全路径名例如java.lang.Object;

  • Integer.toHexString(hashCode()); 将哈希值转成16进制数格式的字符串。

wait 和 notify

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) 效果一样。

ublic final native void notify(); public final native void notifyAll();

首先是 notify ,notify 的作用就是随机唤醒在等待队列的某个线程,而 notifyAll 就是唤醒在等待队列的所有线程。

注意:notify 和 wait 方法的使用规范。意思就是这二者必须在 synchronized 修饰的同步方法或同步代码中使用。

Thread.sleep() 和 Object.wait() 有什么区别?

首先,二者都可以暂停当前线程,释放 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 {     } }

到此,相信大家对"Java基础之如何理解Object源码"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

对象 方法 线程 两个 就是 状态 同步 拷贝 地址 整数 程序 结果 不同 一致 作用 内存 同时 字符 字符串 成员 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 小米移动互联网科技园 中关村互联网 科技集团 天津摩尔互联网科技 甘肃拓世互联网科技有限公司 滨湖区互联网智能科技产品供应 银川新华互联网科技学校地址 互联网金融中的现代科技 互联网为啥属于高科技 昭通互联网科技选哪家 明优互联网科技有限公司 美国互联网科技实力 互联网金融科技元年 互联网公司高科技产品 广州千川互联网科技有限公司 互联网与数字科技关系 广西泛欧互联网科技有限公司 深圳互联网科技园地址 互联网科技品牌 银川新华互联网科技学校招聘 现代科技的标志之一的互联网 华服互联网科技靠谱吗 奇酷互联网络科技 西安互联网科技公司 中国最先进互联网科技公司 福建科技产业互联网发展 广东工业互联网大赛深圳学泰科技 宇信科技在杭州互联网排第几 工业互联网科技创业 互联网科技和医药行业 绵阳真晨互联网科技有限公司
0