Object类常用方法及面试题总结

关于Java常用Api的总结
1.Object
1.1概念
所有对象的顶级父类
存在于java.lang包中
Object类中的方法
object类中方法说明如下:
1 registerNatives() //私有方法
2 getClass() //返回此 Object 的运行类。
3 hashCode() //用于获取对象的哈希值。
4 equals(Object obj) //用于确认两个对象是否“相同”。
5 clone() //创建并返回此对象的一个副本。
6 toString() //返回该对象的字符串表示。
7 notify() //唤醒在此对象监视器上等待的单个线程。
8 notifyAll() //唤醒在此对象监视器上等待的所有线程。
9 wait(long timeout) //在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或 者超过指定的时间量前,导致当前线程等待。
10 wait(long timeout, int nanos) //在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量前,导致当前线程等待。
11 wait() //用于让当前线程失去操作权限,当前线程进入等待序列
12 finalize() //当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。
各论:
1 native
因为 Object 类里面有很多地方都用到 native 关键字。我们先了解一下这家伙。native 关键字是 JNI(Java Native Interface)的重要体现。什么是 JNI ,JNI 是Java调用其他语言(c,c++) 的一种机制。native 关键字修饰的是方法,起声明作用,告诉 JVM 老哥自己去调用这个方法。这个方法的实现在别的语言那里已经实现,我们是看不到源码的。

初始化

1private static native void registerNatives();
2static {
3 registerNatives();
4}
2 hashCode() 方法

1public native int hashCode();
getClass()方法被native修饰,告诉 JVM 自己去调用,可以被重写。同时被 final 修饰,所以不能被子类重写。该方法主要是返回对象的hashcode,主要是为了一些哈希表的数据结构服务的,比如 HashMap 。

在 Java 中hancode 与 对象是否相等密切相关。如果两个对象相等,则 hashcode 一定相等,但是 hashcode 相等,两个对象不一定相等。如果 hashcode 不相等,那么这两个对象一定不相等。
3 equals(Object obj)

1public boolean equals(Object obj) {
2 return (this == obj);
3}
该方法可以被重写,主要用来判断两个对象是否相等。
该方法有一些约定。
对象任意一个非空对象x, x.equals(x) 返回 true。
对象任意两个非空对象 x,y,如果 x.equals(y) 返回true,那么 y.equals(x) 也会返回true, 具有对称性。
对象任意三个非空对象 x,y,z,如果 x.equals(y) 返回true, y.equals(z) 返回true, 那么x.equals(z) 返回true, 具有传递性。
对象任意两个非空对象 x,y,在什么发生变化的情况写,x.equals(y) 返回总是 true 或者 flase,具有一直性。
对象任意一个非空对象x, x.equals(null) 返回 false。
Object#equals(Object obj)方法,比较的是内存地址,通常实际应用中我们想比较的是两个对象里面的属性内容是否相等,所以会重写该方法。这里要注意重写 equals(Object obj) 的时候,也要重写 hashCode() 方法。因为 Java 规定:如果两个对象相等,那么他们的 hashcode 也要相等。举个 Integer 的例子:

1@Override
2public boolean equals(Object obj) {
3 if (obj instanceof Integer) {
4 return value == ((Integer)obj).intValue();
5 }
6 return false;
7}
8
9@Override
10public int hashCode() {
11 return Integer.hashCode(value);
12}
13
14public static int hashCode(int value) {
15 return value;
16}
4 clone()

1protected native Object clone() throws CloneNotSupportedException;
该方法被native修饰,告诉 JVM 自己去调用。当我们在自定义类中使用该方法的时候,需要继承一个 Cloneable 接口,否则会抛出无法克隆的异常。该方法是一个浅复制,不是深复制。

浅拷贝:对基本数据类型进行值传递,对引用数据类型进行引用传递般的拷贝,此为浅拷贝。
深拷贝:对基本数据类型进行值传递,对引用数据类型,创建一个新的对象,并复制其内容,此为深拷贝。

使用代码
1@Data
2public class Person extends Man implements Cloneable {
3 private String name;
4 private Person person;
5
6 public static void main(String[] args) throws CloneNotSupportedException {
7 Person person = new Person();
8 person.setName(“chen”);
9 Person clone = (Person)person.clone();
10 System.out.println(clone.toString());
11 System.out.println(“person.equals(clone):”+person.equals(clone));
12 System.out.println(“person == clone:”+(person == clone));
13 System.out.println(“person.person == clone.person:”+(person.person == clone.person));
14 }
结果
1Person(name=chen, person=null)
2person.equals(clone):true
3person == clone:false
4person.person == clone.person:true
5 notify()、notifyAll() 和 wait()

1public final native void notify();
2public final native void notifyAll();
3public final void wait() throws InterruptedException {
4 wait(0);
5 }
notify() 随机唤醒一个等待线程,notifyAll() 唤醒全部的等待线程。wait() 方法让当前线程进入等待状态。
在这里插入图片描述
无论当前线程调用哪个方法,都有一个前提:当前线程拥有对象的监视器。实现方法也很简单,配合 synchronized 关键字使用。

实现方法
1synchronized (obj) {
2 while (true)
3 obj.wait();
4 // obj.notify();
5}
举一个实际的例子

多线程打印奇偶数
1public static void main(String[] args) {
2 Thread thread = new Thread(() -> {
3 for ( int i = 0; i < 100; i += 2) {
4 synchronized (a) {
5 System.out.println(Thread.currentThread().getName()+":"+i);
6 try {
7 a.wait();
8 } catch (InterruptedException e) {
9 e.printStackTrace();
10 }
11 }
12 }
13 });
14 Thread thread1 = new Thread(() -> {
15 for (int i = 1; i < 100; i += 2) {
16 synchronized (a) {
17 System.out.println(Thread.currentThread().getName()+":"+i);
18 a.notify();
19 }
20 try {
21 Thread.sleep(200);
22 } catch (InterruptedException e) {
23 e.printStackTrace();
24 }
25 }
26 });
27 thread.start();thread1.start();
28 }
6 finalize()

1protected void finalize() throws Throwable { }
当垃圾回收器确定不再有对该对象的引用时,由垃圾回收器在对象上调用该方法。该方法只会被调用一次。

参考
面试中易混点辨析
1.==和equals区别
==:基本类型比较值是否相同
引用类型比较内存地址是否相同
equals:引用类型:object类比较的是地址值但是其他类大都重写了equals方法比较成员变量的值是否相同
2.hashcode()和equals()的区别
hashCode()方法和equal()方法的作用其实一样,在Java里都是用来对比两个对象是否相等一致,

因为重写的equal()里一般比较全面比较复杂,这样效率就比较低,而利用hashCode()进行对比,则只要生成一个hash值进行比较就可以了,效率很高,那么hashCode()既然效率这么高为什么还要equal()呢?

因为hashCode()并不是完全可靠,有时候不同的对象他们生成的hashcode也会一样(生成hash值得公式可能存在的问题),所以hashCode()只能说是大部分时候可靠,并不是绝对可靠

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值