不通过构造函数来创建类的实例 - Unsafe的使用

我们知道,当使用反射构造类的实例时,我们常会用到xxx.class.newInstance()这个方法。但是这个方法有一个限制,就是要求类必须有默认的构造函数。但我们在做框架的时候,很难保证要动态构造的类实例,都是有默认构造函数的,那怎么办呢?

其实用过C++或者Delphi的都知道,其实构造一个对象,分配内存和调用构造函数实际是两个不同的步骤。我们要创建一个对象,实际只需要分配它的内存就可以了

那Java中是否有这样的解决方案呢?答案是:有的其实在使用xstream做反序列化时,我一直就觉得很神奇,明明我要反序列化的对象是没有默认构造函数的,它居然也能把它反序列化出来,这到底是怎么弄的呢?于是我跟踪了源代码,就发现了一个Java中很隐蔽的东西,那就是Unsafe类。这个类默认是被隐藏了起来的,甚至连包名都要手动敲(sun.misc.Unsafe),它的用法是这样的:

Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");

unsafeField.setAccessible(true);

Unsafe u = (Unsafe) unsafeField.get(null);

MyObject obj = (MyObject) u.allocateInstance(MyObject.class);

我们可以看到,这段代码,实际就是绕过了构造函数,只分配了对象实例。这样我们就可以拿着对象实例进行各种操作了。这为反序列化,还有框架的构建,带来了极大的方便,不会有“需要默认构造函数”这样的认为约束了

猜你喜欢

转载自blog.csdn.net/Harryfin/article/details/84619390
今日推荐