聊聊序列化(二)使用sun.misc.Unsafe绕过new机制来创建Java对象

本文探讨了在Java序列化过程中如何创建对象,特别是当类仅提供有参构造函数时的挑战。文章介绍了常规的Java创建对象方式,并指出使用反射和Constructor对象的限制。为了解决这个问题,文章提出了使用`sun.misc.Unsafe`的`allocateInstance()`方法,该方法可以直接分配内存创建对象,跳过了调用构造函数的步骤,避免了因构造函数参数验证导致的异常。文章还提到了在Eclipse中引用`Unsafe`类的注意事项。
摘要由CSDN通过智能技术生成

在序列化的问题域里面有一个常见的问题,就是反序列化时用何种方式来创建Java对象,因为反序列化的目的是把一段二进制流转化成一个对象。

在Java里面创建对象有几种方式:

1. 显式地调用new语句, 比如 DemoClass demo = new DemoClass()

2. 利用反射机制,通过Class对象的newInstance()方法,比如DemoClass demo = DemoClass.class.newInstance()。 但是有个前提就是必须提供无参的构造函数

3. 利用反射机制,利用Constructor对象来创建对象

这三种方式本质上都是一样的,都是常规的Java创建对象的new机制,不管是显式地还是隐式的。一个new操作,编译成指令后是3条

第一条指令的意思是根据类型分配一块内存区域

第二条指令是把第一条指令返回的内存地址压入操作数栈顶

第三条指令是调用类的构造函数


new机制有个问题就是:. 当类只提供有参的构造函数时,必须使用这个有参的构造函数。

那么问题来了,当反序列化的时候,不可能使用显示地new操作,因为肯定地根据传过来的类型动态地调用。利用newInstance肯定没戏了,因为不能确定这个类是否提供了无参构造函数。只能第三种,利用反射机制,使用Constructor对象来创建对象。

但是Consturctor对象有个约束,就是需要提供参数的类型列表,然后使用Constructor.newInstance方法需要传递相应个数的参数。

在反序列化这个场景下,可以这么做:先根据反射获得Constructor的参数类型列表,然后根据每种类型,构造一个对应的默认值的列表,然后调用Constructor.newInstance()方法。这样可以创建出

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值