Object源码(JAVA)

我们都知道,JAVA是门面向对象语言,也就是说,JAVA中对象的地位是极高的。

遍观JDK源码,所有的类都继承自始祖级别的类:Object类。

Object类内部的方法有如下这些:

方法 说明
getClass() 获得该对象的Class类对象
clone() 克隆一份新对象,两个对象不==,但equals
toString() 以字符串形式,输出对象信息
hashCode() 获得该对象的哈希码
equals() 判断两个对象内容是否相等
finalize() 用于GC,当算法将该对象放入待清除队列后会尝试调用该方法一次
wait() 使得当前线程释放该对象的锁,让该对象恢复自由
notify() 唤醒一个等待该对象的线程,使得该对象被线程拥有
notify() 给所有等待的线程发去唤醒消息

源码

  1. toString():该函数仅仅打印出对象所属的类+‘@’+对象哈希码

    1
    2
    3
    public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }
  2. equals():平时我们说==equals是不同的两种东西,但这里的equals内部就是用了==来作比较。

    1
    2
    3
    public boolean equals(Object obj) {
    return (this == obj);
    }
  3. hashCode():这里Object的hashCode方法没有实现,可以看一下String的hashCode是怎么实现的。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // 以下是String的hashCode()
    public int hashCode() {
    int h = hash;
    if (h == 0 && value.length > 0) {
    char val[] = value;

    for (int i = 0; i < value.length; i++) {
    h = 31 * h + val[i];
    }
    hash = h;
    }
    return h;
    }

可见String在计算哈希码前会尝试返回上一次已经计算出来的结果,为什么要乘以31再加上字符的ANSC码呢?

  • 第一,乘上一个数是为了分权重(越在前面的字符在哈希码中权值越大,这使得前缀相同长度相同的字符串的哈希码差不多大,可以存放在相邻的地方)。
  • 第二,乘上31是因为31是素数,可以增大结果的唯一性