Java 对象创建方式
面试官问:"Java 创建对象有哪些方式?"
候选人小程答:"可以用 new 关键字。"
面试官追问:"还有呢?"
小程说:"反射?clone?"
面试官追问:"具体怎么用?有什么区别?"
小程答不全。
【面试官心理】 这道题看似简单,但能完整说出五种方式并理解其适用场景的候选人不多。这是 Java 基础的综合题,考查候选人的知识广度。
一、创建对象的五种方式 🔴
二、new 关键字 🔴
过程:
- 加载类(如果还没加载)
- 在堆中分配内存
- 设置对象头(Mark Word、Klass 指针、数组长度)
- 调用构造器初始化字段
三、反射创建对象 🔴
3.1 Class.newInstance()(JDK 9 废弃)
3.2 Constructor.newInstance()(推荐)
优势:
- 可以调用任意构造器(包括 private)
- 支持有参构造器
- 是 Java 反射 API 的标准方式
3.3 Spring 中的反射
四、clone() 方法 🔴
特点:
- 不需要调用构造器
- 默认是浅拷贝
- 必须实现
Cloneable接口 - 性能好于反射
五、序列化创建对象 🔴
特点:
- 不需要目标类实现任何接口(除了 Serializable)
- 自动深拷贝整个对象图
- 性能较慢
六、Unsafe 创建对象 🔴
特点:
- 不调用构造器
- 可以分配任意大小的内存
- 用于高性能框架(Dubbo、Netty、FastJSON)
⚠️
Unsafe.allocateInstance() 不会执行构造器,字段保持零值。这是危险的,但有时也是有用的(如 Hessian 序列化框架需要跳过构造器)。
七、性能对比 🟡
八、生产中的选择 🟡
九、追问升级
面试官:"一个对象创建需要经历哪些步骤?"
【面试官心理】 能说出对象创建完整步骤(类加载检查→内存分配→对象头设置→零值初始化→构造器)的候选人,说明对 JVM 内存模型有深入理解。这是 P6+ 的要求。