Object类中有哪些方法呢?

杨幂 Java面经 发布时间:2022-05-21 15:28:20 阅读数:8520 1
下文笔者讲述Object类中的方法简介说明,如下所示:
Object类中所包含的方法:
      构造函数,hashCode、equals、toString
	  wait、notify、clone等方法

hashCode、equals、toString

Object是所有类的超类,它里面常见的几个方法 ,这几个方法也是平时在子类中最常重写的方法。

wait、notify

还有wait、notify方法,需要和 synchronized 搭配使用,可以实现一个简易的 生产者-消费者模式。

clone

clone,finalize,这两个方法都是protected修饰的,
不能直接调用,子类想调用这两个方法必须重写。

1、先说一下clone方法,子类重写clone方法,可以直接调用父类Object的clone,它是个native方法,它的克隆算是浅克隆,虽然克隆出来的实例对象是一个新对象,但是如果原实例对象里有引用对象是共享的,意思就是修改原对象中的引用对象中的属性值,克隆对象中的引用对象的属性值也会被修改。

2、调用父类Object 的clone还需要注意,子类必须实现一个接口 Cloneable,它就是一个空接口,里面没有方法定义,目的就是标识这个类支持克隆,如果没有实现接口Cloneable,就会抛一个 CloneNotSupportedException 异常。

3、如果想实现深克隆,就得自己实现克隆的逻辑,比如自己new一个新对象,然后把引用对象也new一下。

4、还可以通过序列化和反序列化实现深克隆,序列化和反序列化可以直接用jdk自带的 ObjectOutputStream 和 ObjectInputStream实现,不过需要注意,序列化的类以及其类的实例对象里的引用对象对应的类都必须实现接口 Serializable ,它也是一个空接口,目的也是标识 该类 支持序列化和反序列化。

5、说到接口Serializable,就不得不说一下 serialVersionUID,序列化和反序列化的过程中,每个可序列化的类都会关联一个版本号,就是 serialVersionUID,在反序列化的时候,会验证序列化对象的发送方和接收方的serialVersionUID是否相等,相等就可以反序列化,不相等就会反序列化失败(InvalidClassException异常)。

6、如果不显式声明serialVersionUID,则序列化运行时将根据类的各个方面计算该类的默认serialVersionUID 值,类似于md5和checksum的作用。但是强烈建议显式声明serialVersionUID,因为缺省的serialVersionUID计算的默认值,会很敏感,可能取决于编译器实现的细节,容易导致意外的反序列化失败InvalidClassExceptions。

7、因此,为了保证不同java编译器实现的serialVersionUID值一致,可序列化的类必须显式声明serialVersionUID值。显式声明的serialVersionUID必须是static、final、long类型的,这样的serialVersionUID只作用于当前类,不会因为继承传播给其子类,也建议serialVersionUID用private修饰,屏蔽外界的访问。serialVersionUID一般可以通过idea快捷键自动生成。

8、实现Serializable的类里如果某些变量不想被序列化,可以声明成static的,如果不能声明成静态的,也可用 transient 修饰。static 和 transient 的作用还是有差别的:

static修饰的变量,是属于类的,自然不会被序列化和反序列化。
transient修饰的非静态变量,不会被序列化,反序列化获取到transient修饰的变量的值是零值,所谓零值就是0或null

9、其他序列化框架

json序列化框架,Jackson、FastJson、Gson
jute序列化,看了zk源码发现,其序列化底层实现还是用的jdk的ObjectOutputStream 和 ObjectInputStream。
Protobuf序列化,Protobuf使用比较广泛,主要是空间开销小和性能比较好,非常适合用于公司内部对性能要求高的RPC调用。protobuf有个缺点就是要传输的每一个类的结构都要生成对应的proto文件,如果某个类发生修改,还得重新生成该类对应的proto文件。
Thrift
Hessian序列化,Hessian是一个支持跨语言传输的二进制序列化协议,Dubbo采用的就是Hessian序列化来实现,只不过Dubbo对Hessian进行了重构,性能更高。
Avro序列化,Avro是apache下hadoop的子项目,拥有序列化、反序列化、RPC功能。
kyro序列化,Kryo是一种非常成熟的序列化实现,已经在Hive、Storm中使用得比较广泛,不过它不能跨语言. 目前dubbo已经在
2.6版本支持kyro的序列化机制。

finalize

finalize 子类也可以重写,默认Object里是个空方法什么也不做
 笔者建议是不要随便重写finalize 方法
  因为finalize 它使得对象的回收变得不确定性。

任何一个对象的finalize方法都只会被系统自动调用一次。什么时候调用呢?

在垃圾回收,收集器遍历GC Roots 进行第一次标记时判断一个对象的finalize是否有必要调用:

如果对象没有重写finalize方法或者被调用过,那就没必要再调用;
如果对象重写了finalize方法且没有被调用过,那么该对象将会被放置到一个队列中(F-Queue),并在稍后由一条由虚拟机自动建立的、低调度优先级Finalizer线程去执行它们的finalize()方法。

finalize()方法是对象逃脱死亡命运的最后一次机会,稍后收集器将对F-Queue中的对象进行第二次小规模的标记:

如果对象要在finalize()中成功拯救自己,只要重新与引用链上的任何一个对象建立关联即可,譬如把自己(this关键字)赋值给某个类变量或者对象的成员变量,那在第二次标记时它将被移出“即将回收”的集合
 
版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

本文链接: https://www.Java265.com/JavaMianJing/202205/16531181493442.html

最近发表

热门文章

好文推荐

Java265.com

https://www.java265.com

站长统计|粤ICP备14097017号-3

Powered By Java265.com信息维护小组

使用手机扫描二维码

关注我们看更多资讯

java爱好者