小红书Java面试被问:java创建对象有哪些方式?

在Java中,创建对象主要有以下五种核心方式,每种方式都有其适用场景:


1. 使用 new 关键字(最常用)

java

复制代码
// 调用构造方法
Person person = new Person();
  • 特点:直接调用类的构造器,触发类加载(如果未加载)、分配内存、初始化等完整过程。

  • 场景:日常开发中最常用的方式。


2. 使用反射机制(Reflection)

通过 Class 类的 newInstance() 或构造器来创建对象。

java

复制代码
// 方式一:Class.newInstance()(JDK9已废弃,推荐使用构造器)
Class<Person> clazz = Person.class;
Person person = clazz.newInstance(); // 需要无参构造,且权限为public

// 方式二:Constructor.newInstance()(更灵活)
Constructor<Person> constructor = clazz.getConstructor(String.class);
Person person = constructor.newInstance("张三");
  • 特点

    • 可以在运行时动态创建对象。

    • 可以调用私有构造器(通过 setAccessible(true))。

  • 场景:框架设计(如Spring IOC)、动态代理、工具类封装。

篇幅限制下面就只能给大家展示小册部分内容了。整理了一份核心面试笔记包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafc

需要全套面试笔记及答案
【点击此处即可/免费获取】​​​


3. 使用 clone() 方法(复制现有对象)

java

复制代码
public class Person implements Cloneable {
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone(); // 浅拷贝
    }
}

// 使用
Person p1 = new Person();
Person p2 = (Person) p1.clone();
  • 特点

    • 不调用构造器,直接复制内存数据。

    • 需要实现 Cloneable 接口(标记接口),否则抛 CloneNotSupportedException

    • 默认为浅拷贝 ,需重写 clone() 实现深拷贝。

  • 场景:复制复杂对象、避免重复创建开销(如原型模式)。


4. 使用反序列化(Deserialization)

java

复制代码
// 对象必须实现 Serializable 接口
try (ObjectInputStream ois = new ObjectInputStream(
        new FileInputStream("person.dat"))) {
    Person person = (Person) ois.readObject(); // 通过字节流重建对象
}
  • 特点

    • 完全不调用构造器,通过二进制数据还原对象。

    • 对象需实现 Serializable 接口。

  • 场景:网络传输、持久化存储恢复对象(如缓存恢复、RPC调用)。


5. 使用工厂方法/构建器模式(间接创建)

java

复制代码
// 静态工厂方法
public class Person {
    public static Person createWithName(String name) {
        Person p = new Person();
        p.setName(name);
        return p;
    }
}
Person p = Person.createWithName("李四");

// Builder模式(Lombok @Builder)
Person person = Person.builder()
                      .name("王五")
                      .age(25)
                      .build();
  • 特点

    • 封装对象创建逻辑,提供更友好的API。

    • 本质上仍调用 new 或反射,但对外隐藏细节。

  • 场景:复杂对象构造、可选参数多、需要创建控制(如单例、缓存池)。


特殊说明:其他边缘方式

  • Unsafe.allocateInstance() :直接分配内存而不初始化对象(Unsafe 类,JVM内部使用,不推荐业务代码使用)。

  • 动态代理(Proxy.newProxyInstance):创建接口的代理对象,属于反射的延伸应用。


对比总结

方式 是否调用构造器 适用场景
new ✅ 调用 常规对象创建
反射 ✅ 可选调用 框架、动态加载
clone() ❌ 不调用 复制现有对象
反序列化 ❌ 不调用 持久化恢复、远程传输
工厂/Builder ✅ 间接调用 复杂构造、代码可读性

篇幅限制下面就只能给大家展示小册部分内容了。整理了一份核心面试笔记包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafc

需要全套面试笔记及答案
【点击此处即可/免费获取】​​​


面试延伸问题

如果面试官深入追问,可以准备以下要点:

  1. newnewInstance() 区别

    • new 是关键字,编译时确定;newInstance() 是反射方法,运行时动态创建。
  2. 反序列化如何破坏单例

    • 反序列化会创建新对象,可通过实现 readResolve() 方法返回单例实例来防御。
  3. 深拷贝 vs 浅拷贝如何实现

    • 浅拷贝:Object.clone() 默认复制字段值(引用类型复制地址)。

    • 深拷贝:递归复制引用对象,或通过序列化/反序列化实现。

掌握这些创建方式,不仅有助于面试,更能加深对Java对象生命周期的理解。

相关推荐
zfj32120 小时前
从源码层面解析一下ThreadLocal的工作原理
java·开发语言·threadlocal
墨笔之风20 小时前
java后端根据双数据源进行不同的接口查询
java·开发语言·mysql·postgres
Mr -老鬼20 小时前
功能需求对前后端技术选型的横向建议
开发语言·前端·后端·前端框架
IT=>小脑虎20 小时前
Go语言零基础小白学习知识点【基础版详解】
开发语言·后端·学习·golang
程序猿阿伟20 小时前
《Python复杂结构静态分析秘籍:递归类型注解的深度实践指南》
java·数据结构·算法
qq_4061761420 小时前
关于JavaScript中的filter方法
开发语言·前端·javascript·ajax·原型模式
黑白极客21 小时前
怎么给字符串字段加索引?日志系统 一条更新语句是怎么执行的
java·数据库·sql·mysql·引擎
爬山算法21 小时前
Hibernate(32)什么是Hibernate的Criteria查询?
java·python·hibernate
醇氧21 小时前
Ping 127.0.0.1 具有 32 字节的数据:一般故障。【二】
运维·服务器·开发语言
码农水水21 小时前
中国邮政Java面试:热点Key的探测和本地缓存方案
java·开发语言·windows·缓存·面试·职场和发展·kafka