Java创建对象时如何不触发已声明的constructor执行且不删除构造方法
结论
正常通过new关键字实例化类对象的场景下,必然会触发构造方法执行,没有绕过的可能。如果不删除现有构造器,仅能通过JVM底层相关的非常规手段创建对象且不触发构造方法执行,常见方案如下:
方案1:使用sun.misc.Unsafe的allocateInstance方法
该方法是JDK提供的底层操作能力,可以直接在堆内存分配对象空间,完全跳过类构造、初始化流程,代码示例:
import sun.misc.Unsafe; import java.lang.reflect.Field; class Test{ Test(){ System.out.println("This is Constructor"); } } public class App { public static void main(String[] args) throws Exception { // 反射获取Unsafe实例 Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe"); unsafeField.setAccessible(true); Unsafe unsafe = (Unsafe) unsafeField.get(null); // 直接分配实例,不会触发构造方法 Test object = (Test) unsafe.allocateInstance(Test.class); System.out.println("对象创建完成,构造方法未执行"); } }
运行后不会输出构造方法内的This is Constructor内容。
方案2:反序列化生成对象
如果目标类实现了Serializable序列化接口,从二进制流反序列化还原对象时,不会触发本类的构造方法,代码示例:
import java.io.*; class Test implements Serializable { Test(){ System.out.println("This is Constructor"); } } public class App { public static void main(String[] args) throws Exception { // 首次new对象会触发构造方法,序列化到本地文件 Test originalObj = new Test(); ObjectOutputStream outStream = new ObjectOutputStream(new FileOutputStream("test.obj")); outStream.writeObject(originalObj); outStream.close(); // 反序列化生成新对象,不会触发Test类构造方法 ObjectInputStream inStream = new ObjectInputStream(new FileInputStream("test.obj")); Test deserializedObj = (Test) inStream.readObject(); inStream.close(); System.out.println("反序列化生成新对象完成,构造方法未执行"); } }
运行后仅首次new对象时会输出构造方法的打印内容,反序列化阶段不会触发构造方法执行。
注意:以上两种都是非常规的对象创建方式,普通业务开发几乎不会用到,日常编码场景下只要使用
new创建对象就一定会触发构造方法执行。
内容的提问来源于stack exchange,提问作者Copernove
相关产品推荐
相关产品推荐

