java 基础回顾 - Object
- Object 是 java 中的基类
- 里面的部分方法经常需要被重写, 所以必须对 Object 内的方法有所了解.
下面是 Object 的部分源码内容和注释
package java.lang;
public class Object {
public Object() {
}
/**
* 拷贝对象, 直接调用是浅拷贝, 重写后通过对非基础类型的属性调用循环调用 clone() 方法实现深拷贝
*/
protected java.lang.Object clone() throws CloneNotSupportedException {
}
/**
* 比较两个对象是否相等, 返回true相等, false 不相等
* 直接调用 == 判断地址, 重写 equals 可以通过属性判断
*/
public boolean equals(java.lang.Object obj) {
//return (this == obj);// 默认只比较内存地址
if (this == obj) {// 1: 内存地址相同,判断为同一个对象,返回true
return true;
}
//obj instanceof Object 替换为 obj.getClass() == this.getClass() 可避免 obj 是子类的情况
if (obj != null && obj instanceof Object) {// 2: 如果比较的对象是同一个类型, 再进行属性值的比较
// 4: 将obj类型强转, 进行属性的比较
}
return false;//3: 默认返回false
}
/**
* 类似析构函数, 在方法中做一些清理工作, 在GC之前调用, 但是不保证一定调用
*/
protected void finalize() throws Throwable {
}
/**
* 返回类型 type, Object 调用 getClass() 返回 class java.lang.Object
*/
public final native Class<?> getClass();
/**
* hashCode() 返回值作为哈希表中的键值, 部分类(如HashMap)使用哈希表快速查找对象
* equals 相等的对象, hashCode 的值要一定相同, 所以重写了 equals 最好把 hashCode 方法也重写
* 《Effective Java》中提出了一种简单通用的hashCode算法
* 1. 初始化一个整形变量,为此变量赋予一个非零的常数值,比如int result = 17;
* 2. 选取equals方法中用于比较的所有域,然后针对每个域的属性进行计算:
* (1) 如果是boolean值,则计算f ? 1:0
* (2) 如果是byte\char\short\int,则计算(int)f
* (3) 如果是long值,则计算(int)(f ^ (f >>> 32))
* (4) 如果是float值,则计算Float.floatToIntBits(f)
* (5) 如果是double值,则计算Double.doubleToLongBits(f),然后返回的结果是long,再用规则(3)去处理long,得到int
* (6) 如果是对象应用,如果equals方法中采取递归调用的比较方式,那么hashCode中同样采取递归调用hashCode的方式。 否则需要为这个域计算一个范式,比如当这个域的值为null的时候,那么hashCode 值为0
* (7) 如果是数组,那么需要为每个元素当做单独的域来处理。
*/
public native int hashCode(){
int result = 17;
int elementHash;// 用于叠加属性的值
// 叠加属性值的运算
result = 31 * result + elementHash;
return result;
}
/**
* 随机唤醒在此对象监视器上等待的单个线程。
*/
public final native void notify();
/**
* 唤醒在此对象监视器上等待的所有线程。
*/
public final native void notifyAll();
/**
* 返回该对象的字符串表示
* 将对象强转成 String 时调用, 返回的值就是强转之后的字符串
* 不重写的话就是 类名@内存地址
*/
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
/**
* 在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。
*/
public final void wait() throws InterruptedException {
}
/**
* 在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量前,导致当前线程等待。
*
* @param millis
*/
public final void wait(long millis) throws InterruptedException {
}
/**
* 在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量前,导致当前线程等待。
*/
public final native void wait(long var1, int var3) throws InterruptedException;
}