文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Java 基础 | Object 源码解析

2024-12-03 16:54

关注

 前言

Java 是一门面向对象的语言,在 Java 里面一切都可以看作是一个对象,而 Java 里面所有的对象都默认继承于 Object 类。

本文基于JDK1.8


可以看到一共12个方法,其中 registerNatives() 是 native 修饰的,一个本地方法,具体是用C(C++)在DLL中实现的,然后通过JNI调用。

getClass

  1. public final native Class getClass(); 

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

hashCode

  1. public native int hashCode(); 

equals

  1. public boolean equals(Object obj) { 
  2.     return (this == obj); 

 equals 的实现非常简单,它的作用就是比较两个对象是否相等,而比较的依据就是二者的内存地址。除此之外,equals 还遵循以下几个原则:

  1. 1、自反性:x.equals(x);  // true 
  2. 2、对称性:x.equals(y) == y.equals(x);  // true 
  3. 3、传递性:if (x.equals(y) && y.equals(z)) 
  4.             x.equals(z); // true
  5. 4、一致性,只要对象没有被修改,多次调用 equals() 方法结果不变: 
  6. x.equals(y) == x.equals(y); // true  
  7. 5、非空性,对任何不是 null 的对象 x 调用 x.equals(null) 结果都为 false : 
  8. x.equals(null); // false

 为什么要重写 hashcode 和 equals ?

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

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

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

clone 

  1. protected native Object clone() throws CloneNotSupportedException; 

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

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

toString

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

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

wait 和 notify

  1. public final void wait() throws InterruptedException { 
  2.      wait(0); 
  3.  
  4. public final native void wait(long timeout) throws InterruptedException; 
  5.  
  6. public final void wait(long timeout, int nanos) throws InterruptedException { 
  7.         if (timeout < 0) { 
  8.             throw new IllegalArgumentException("timeout value is negative"); 
  9.         } 
  10.  
  11.         if (nanos < 0 || nanos > 999999) { 
  12.             throw new IllegalArgumentException( 
  13.                                 "nanosecond timeout value out of range"); 
  14.         } 
  15.  
  16.         if (nanos > 0) { 
  17.             timeout++; 
  18.         } 
  19.  
  20.         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) 效果一样。

  1. ublic final native void notify(); 
  2. public final native void notifyAll(); 

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

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

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

首先,二者都可以暂停当前线程,释放 CPU 控制权。主要的区别在于 Object.wait()在释放 CPU 同时,释放了对象锁的控制。而 Thread.sleep() 没有对锁释放。换句话说 sleep 就是耍流氓,占着茅坑不拉屎。

完整代码

  1. package java.lang; 
  2.  
  3.  
  4. public class Object { 
  5.  
  6.      
  7.     private static native void registerNatives(); 
  8.  
  9.      
  10.     static { 
  11.         registerNatives(); 
  12.     } 
  13.  
  14.      
  15.     public final native Class getClass(); 
  16.  
  17.      
  18.     public native int hashCode(); 
  19.  
  20.      
  21.     public boolean equals(Object obj) { 
  22.         return (this == obj); 
  23.     } 
  24.  
  25.      
  26.     protected native Object clone() throws CloneNotSupportedException; 
  27.  
  28.      
  29.     public String toString() { 
  30.         return getClass().getName() + "@" + Integer.toHexString(hashCode()); 
  31.     } 
  32.  
  33.      
  34.     public final native void notify(); 
  35.  
  36.      
  37.     public final native void notifyAll(); 
  38.  
  39.      
  40.     public final native void wait(long timeout) throws InterruptedException; 
  41.  
  42.  
  43.     public final void wait(long timeout, int nanos) throws InterruptedException { 
  44.         if (timeout < 0) { 
  45.             throw new IllegalArgumentException("timeout value is negative"); 
  46.         } 
  47.  
  48.         if (nanos < 0 || nanos > 999999) { 
  49.             throw new IllegalArgumentException( 
  50.                     "nanosecond timeout value out of range"); 
  51.         } 
  52.  
  53.         if (nanos > 0) { 
  54.             timeout++; 
  55.         } 
  56.  
  57.         wait(timeout); 
  58.     } 
  59.  
  60.      
  61.     public final void wait() throws InterruptedException { 
  62.         wait(0); 
  63.     } 
  64.  
  65.      
  66.     protected void finalize() throws Throwable { 
  67.     } 

 PS:这里有一个技术交流群(扣扣群:1158819530),方便大家一起交流,持续学习,共同进步,有需要的可以加一下。

 

来源:今日头条内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯