Object类

Object类

【摘要】Java类层次结构是一棵倒置的“树”,根就是Object~

前言

hi~

Object

废话不多说,先怼源码!下面这段代码是JDK1.8中的Object。其他版本的咱也没看,咱也不多扯。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package java.lang;
public class Object {
private static native void registerNatives();
static {
registerNatives();
}
public final native Class<?> getClass();
public native int hashCode();
public boolean equals(Object obj) {
return (this == obj);
}
protected native Object clone() throws CloneNotSupportedException;
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
public final native void notify();
public final native void notifyAll();
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);
}
public final void wait() throws InterruptedException {
wait(0);
}
protected void finalize() throws Throwable { }
}

学习和了解Java里面的终极父类Object也就是弄清楚上面每个方法也就可以了。

registerNatives方法

静态代码块是一个类在初始化过程中必定会执行的内容,所以在类加载时会执行该方法,通过该方法来注册本地方法。

getClass方法

getClass方法用来获取对象的编译时类型。任一类型在JVM中的实例只有一个。
如:

1
2
3
4
5
6
Book b1 = new Book(...);
Book b2 = new book();
//
Class<Book> c1 = b1.getClass();
Class<Book> c2 = b2.getClass();
System.out.println(c1 == c2);//true

Class是用来表示类型的类型,任何一个类型,被加载进JVM后,它在JVM中类型都是Class。

hashcode方法

hashcode方法, 用来生成哈希码值,它是为了将来通过哈希算法存储数据时所需要调用的,目的是计算出具体的位置。默认的实现就是内存地址的码值。如果你想与equals方法保持一致,则也应该重写此方法。

equals方法

equals方法,用来判断两个对象是否”相等”,它的默认实现就是比地址。同==如果你想从逻辑上去比较两个对象是否相等,则应该重写equals方法。

注:
hashcode和equals方法是“联动”的,它有如下关系:
A. equals返回true的两个对象的哈希码值必需一样
B. equals返回false的两个对象的哈希码值要尽最努力保持不一样。
如:

1
2
3
4
5
6
7
8
9
10
11
public class Student {
private String stuNo;
private String name;
private int age;
//...
}
Student s1 = new Student("1001","ZhangYao",18);
Student s2 = new Student("1001","ZhangYao",18);
System.out.println(s1); //会打印出什么呢?
System.out.println(s1.equals(s2)); // false 如果重写了比较逻辑,则会返回true
System.out.println(s1 == s2); //false

clone方法

如:

1
2
3
4
5
6
7
8
9
10
11
12
Book b1 = new Book("人类群星闪耀时","茨威格",19.8);
Book b2 = b1;//这不叫克隆[此时b2和b1指向同一个对象]
b2.setPrice(45.6);
//
System.out.printl(b1.getPrice());//45.6

//克隆
public calss UseBook{
public static void main(String[] args){
Book b3 = b1.clone();
}
}

注:
Object类的clone方法的实现只完成了 浅拷贝,是指COPY了基本类型的属性以及实现了Cloneable接口的对象类型属性,如:String ,Date,而对于没有实现的Cloneable接口的对象类型属性,则还是会“共用”。

toString方法

toString 方法,把对象以字符串的形式表达出来。它的默认实现是把对象的内存地址以16进制方式表达出来。所以,在你的类中应该去重写 toString方法。

notify方法

notifyAll方法

wait方法

finalize方法

finalize方法,当一个对象被GC回收之前,JVM会调用这个对象的finalize方法。
虽然这个方法的目的很明确,但是,对象被GC回收的时机确时不确定的。
所以,JVM调用此方法的时机也就是不确定的。
如:

1
2
3
4
5
6
7
Book b1 = new Book();
//如何让这个对象被“GC”看上呢?
b1 = null;
//此时,按道理,GC会去回收这个对象,但是,时机并不确定。因为GC的执行时机,程序员是不能强制的,它有自己的打算。

//可以尝试去 催促 GC ,比如调用这个方法:
System.gc();

结束语

bye~

评论