专注Java教育14年 全国咨询/投诉热线:400-8080-105
动力节点LOGO图
始于2009,口口相传的Java黄埔军校
首页 学习攻略 Java父类Object的终极理解

Java父类Object的终极理解

更新时间:2020-07-28 16:29:29 来源:动力节点 浏览2093次

一、定义

(一)什么是object类

1.Object类存储在java.lang包中,使用的时候无需显示导入,编译时由编译器自动导入。是所有java类(Object类除外)的终极父类(包括标准容器类,比如数组),不过接口不继承Object类。

2.可以使用类型为Object的变量指向任意类型的对象。Object类的变量只能用作各种值的通用持有者,要对他们进行任何专门的操作,都需要知道它们的原始类型并进行类型转换。

3.包含的函数:

1)public Object();

2)protected Object clone()

3)boolean equals(Object obj)

4)protected void finalize()

5)Class<>getClass()

6)int hashCode()

7)void notify()

8)void notifyAll()

9)String toString()

10)void wait()

11)void wait(long timeout)

12)void wait(long timeout,int nanos)

二、用法

(一)常用函数解析

1.Object():默认构造方法。

1)Java中规定:在类定义过程中,对于未定义构造函数的类,默认会有一个无参数的构造函数,作为所有类的基类,Object类自然要反映出此特性,在源码中,未给出Object类构造函数定义,但实际上,此构造函数是存在的。当然,并不是所有的类都是通过此种方式去构建,也自然的,并不是所有的类构造函数都是public。

2.Clone():创建并返回此对象的一个副本。

1)clone()方法又是一个被声明为native的方法,因此,我们知道了clone()方法并不是Java的原生方法,具体的实现是有C/C++完成的。clone英文翻译为"克隆",其目的是创建并返回此对象的一个副本。clone函数返回的是一个引用,指向的是新的clone出来的对象,此对象与原对象分别占用不同的堆空间。

2)当代码执行的时候,将会检查调用对象的类(或者父类)是否实现了java.lang.Cloneable接口(Object类不实现Cloneable)。如果没有实现这个接口,clone()将会抛出一个检查异常()——java.lang.CloneNotSupportedException,如果实现了这个接口,clone()会创建一个新的对象,并将原来对象的内容复制到新对象,最后返回这个新对象的引用。

3)浅克隆(也叫做浅拷贝)仅仅复制了这个对象本身的成员变量,该对象如果引用了其他对象的话,也不对其复制仅仅复制其引用(当被复制的对象的引用类型变量内容发生变化时候,被复制的对象也会跟着变化)。

3.finalize():当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。

1)首先,Object中定义finalize方法表明Java中每一个对象都将具有finalize这种行为,其具体调用时机在:JVM准备对此对形象所占用的内存空间进行垃圾回收前,将被调用。由此可以看出,此方法并不是由我们主动去调用的(虽然可以主动去调用,此时与其他自定义方法无异)。

4.equals()与hashCode():指示某个其他对象是否与此对象“相等”;返回该对象的哈希码值。

1)重写equals()方法必须重写hashCode()方法。因为当仅仅重写equals()方法改变了判断对象相等条件,但是很多引用类型(例如hashMap等)判断相等是通过hashCode()方法判断key值是否相等,所以会导致意想的equals()要相等,但是hashCode()依旧是之前的逻辑导致不相等。

2)对象相等óequals()相等=>hashCode()相等;根据逆反定理:hashCode()不相等=>equals()不相等ó对象不相等

3)hashCode()相同的两个对象不一定相等,换而言之不相等的两个对象其hashCode()值可能相同。

5.getClass():返回一个对象的运行时类。

1)首先解释下"类对象"的概念:在Java中,类是对具有一组相同特征或行为的实例的抽象并进行描述,对象则是此类所描述的特征或行为的具体实例。作为概念层次的类,其本身也具有某些共同的特性,如都具有类名称、由类加载器去加载,都具有包,具有父类,属性和方法等。于是,Java中有专门定义了一个类,Class,去描述其他类所具有的这些特性,因此,从此角度去看,类本身也都是属于Class类的对象。为与经常意义上的对象相区分,在此称之为"类对象"。

6.toString:返回该对象的字符串表示。

1)在Object类中,它用于返回对象所属类名和散列码。

2)绝大多数的toString方法都遵循这个格式:类名[域值,域值,域值......]。

7.notify()、notifyAll():唤醒在此对象监视器上等待的单个/所有线程。

1)调用后,其所在线程不会立即释放所持有的锁,直到其所在同步代码块中的代码执行完毕,此时释放锁,因此,如果其同步代码块后还有代码,其执行则依赖于JVM的线程调度。

8.wait()、wait(long timeout)、wait(long timeout,int nanos):导致当前的线程等待,直到其他线程调用此对象的notify()方法或notifyAll()方法、或者已超过某个实际时间量,、或者其他某个线程中断当前线程。

1)调用后当前线程将立即阻塞,且释放其所持有的同步代码块中的锁,直到被唤醒或超时或打断后且重新获取到锁后才能继续执行。

三、总结

1.既然比较两个对象是否相等的唯一条件(也是冲要条件)是equals,那么为什么还要弄出一个hashCode(),并且进行如此约定,弄得这么麻烦?

1)其实,这主要体现在hashCode()方法的作用上,其主要用于增强哈希表的性能。

2)以集合类中,以Set为例,当新加一个对象时,需要判断现有集合中是否已经存在与此对象相等的对象,如果没有hashCode()方法,需要将Set进行一次遍历,并逐一用equals()方法判断两个对象是否相等,此种算法时间复杂度为o(n)。通过借助于hasCode方法,先计算出即将新加入对象的哈希码,然后根据哈希算法计算出此对象的位置,直接判断此位置上是否已有对象即可。(注:Set的底层用的是Map的原理实现)

2.在程序执行期间,只要equals方法的比较操作用到的信息没有被修改,那么对这同一个对象调用多次,hashCode方法必须始终如一地返回同一个整数。

1)设计hashCode()时最重要的因素就是:无论何时,对同一个对象调用hashCode()都应该产生同样的值。如果在讲一个对象用put()添加进HashMap时产生一个hashCdoe值,而用get()取出时却产生了另一个hashCode值,那么就无法获取该对象了。所以如果你的hashCode方法依赖于对象中易变的数据,用户就要当心了,因为此数据发生变化时,hashCode()方法就会生成一个不同的散列码。

2)因此,在设计hashCode方法和equals方法的时候,如果对象中的数据易变,则最好在equals方法和hashCode方法中不要依赖于该字段。

3.大多数人认为hashCode返回的就是对象的存储地址,事实上这种看法是不全面的,确实有些JVM在实现时是直接返回对象的存储地址,但是大多时候并不是这样,只能说可能存储地址有一定关联。

Java父类Object的终极理解

Java Object类技术文档:http://www.bjpowernode.com/tutorial_java_advance/606.html

以上就是动力节点java培训机构的小编针对“Java父类Object的终极理解”的内容进行的回答,希望对大家有所帮助,如有疑问,请在线咨询,有专业老师随时为你服务。

提交申请后,顾问老师会电话与您沟通安排学习

免费课程推荐 >>
技术文档推荐 >>