前言
Java 中的 Object 方法在面试中是一个非常高频的点,毕竟 Object 是所有类的“老祖宗”。Java 中所有的类都有一个共同的祖先 Object 类,子类都会继承所有 Object 类中的 public 方法。
先看下 Object 的类结构:
1. getClass 方法
|
final 方法、获取对象的运行时 class 对象,class 对象就是描述对象所属类的对象。这个方法通常是和 Java 反射机制搭配使用的。
2. hashCode 方法
1 |
|
该方法主要用于获取对象的散列值。Object 中该方法默认返回的是对象的堆内存地址。
3. equals 方法
1 |
|
该方法用于比较两个对象,如果这两个对象引用指向的是同一个对象,那么返回 true,否则返回 false。一般 equals 和 == 是不一样的,但是在 Object 中两者是一样的。子类一般都要重写这个方法。
重写equals为什么还要重写hashcode
1、为了保证一个原则,equals相同的两个对象hashcode必须相同。如果重写了equals而没有重写hashcode,会出现equals相同hashcode不相同这个现象。
2、在散列集合中,是使用hashcode来计算key应存储在hash表的索引,如果重写了equals而没有重写hashcode,会出现两个完全相同的两个对象,hashcode不同,计算出的索引不同,那么这些集合就乱套了。
3、提高效率,当我们比较两个对象是否相同的时候,先比较hashcode是否相同,如果hashcode不相同肯定不是一个对象,如果hashcode相同再调用equals来进行比较,减少比较次数提高效率。
4. clone 方法
1 |
|
该方法是保护方法,实现对象的浅复制,只有实现了 Cloneable 接口才可以调用该方法,否则抛出 CloneNotSupportedException 异常。
当你使用 clone()
方法克隆一个对象时,会创建一个新的对象,但是对象的引用类型字段(如 Address
类型的 address
字段)仍然指向相同的对象。
而对于基本类型字段和String(如 Integer
类型的 age 字段,String类型的name),Java 中的自动装箱和拆箱特性会使得对象在被克隆时被重新分配内存,从而修改副本对象中的该字段不会影响原对象。
5. toString 方法
1 |
|
返回一个 String 对象,一般子类都有覆盖。默认返回格式如下:对象的 class 名称 + @ + hashCode 的十六进制字符串。
6. notify 方法
1 |
|
final 方法,主要用于唤醒在该对象上等待的某个线程。
7. notifyAll 方法
1 |
|
final 方法,主要用于唤醒在该对象上等待的所有线程。
8. wait(long timeout) 方法
1 |
|
wait 方法就是使当前线程等待该对象的锁,当前线程必须是该对象的拥有者,也就是具有该对象的锁。wait() 方法一直等待,直到获得锁或者被中断。wait(long timeout) 设定一个超时间隔,如果在规定时间内没有获得锁就返回。
9. wait(long timeout, int nanos) 方法
1 |
|
参数说明
- timeout:最大等待时间(毫秒)
- nanos:附加时间在毫秒范围(0-999999)
该方法导致当前线程等待,直到其他线程调用此对象的 notify() 方法或notifyAll()方法,或在指定已经过去的时间。此方法类似于 wait 方法的一个参数,但它允许更好地控制的时间等待一个通知放弃之前的量。实时量,以毫微秒计算,计算公式如下:1000000 * timeout + nanos
在所有其他方面,这种方法与 wait(long timeout) 做同样的事情。特别是 wait(0, 0) 表示和 wait(0) 相同。
10. wait 方法
1 |
|
可以看到 wait() 方法实际上调用的是 wait(long timeout) 方法,只不过 timeout 为 0,即不等待。
11. finalize 方法
1 |
|
该方法是保护方法,主要用于在 GC 的时候再次被调用,如果我们实现了这个方法,对象可能在这个方法中再次复活,从而避免被 GC 回收。