Java 大厂面试高频题:别再只会 new 了!Java 创建对象竟然有这么多种方式

发布时间:2026/11/1 6:35:00

Java 大厂面试高频题:别再只会 new 了!Java 创建对象竟然有这么多种方式 在学习 Java 时我们最先接触的对象创建方式通常是PersonpersonnewPerson();因此很多初学者会认为 Java 创建对象只能使用new。实际上Java 中常见的对象创建方式不止一种。除了直接使用new还可以通过反射、克隆、反序列化、工厂方法等方式获得对象。本文将介绍 Java 中常见的 6 种对象创建方式1. 使用 new 关键字 2. 使用反射调用构造方法 3. 使用 Class.newInstance() 4. 使用 clone() 克隆对象 5. 使用反序列化创建对象 6. 使用工厂方法获得对象在理解这些方式之前需要先明确对象、引用变量和类不是同一个概念。一、什么是创建对象先定义一个简单的Person类classPerson{privateStringname;publicPerson(){System.out.println(Person 构造方法执行了);}publicPerson(Stringname){this.namename;System.out.println(有参构造方法执行了);}publicvoidsayHello(){System.out.println(你好我是name);}}创建对象时通常写PersonpersonnewPerson();这句代码可以拆成三部分Person变量的类型 person引用变量 new Person()创建 Person 对象真正创建出来的对象是newPerson()person只是一个引用变量它保存了对这个对象的引用。可以类比为Person 类房屋设计图 Person 对象根据设计图建出的房子 person 变量房子的门牌号接下来看看 Java 创建对象的不同方式。二、方式一使用 new 关键字使用new是最常见、最直接的对象创建方式。PersonpersonnewPerson();也可以调用有参构造方法PersonpersonnewPerson(张三);执行new Person(张三)时Java 大致会完成以下操作1. 在堆内存中为 Person 对象分配空间 2. 为成员变量设置默认值 3. 执行成员变量的显式初始化 4. 执行构造代码块 5. 调用对应的构造方法 6. 返回新对象的引用。使用publicclassTest{publicstaticvoidmain(String[]args){PersonpersonnewPerson(张三);person.sayHello();}}输出有参构造方法执行了 你好我是张三特点语法简单 可读性强 会调用构造方法 是日常开发中最常用的方式。大多数情况下创建普通业务对象都应该优先使用new。三、方式二使用反射调用构造方法反射允许程序在运行过程中动态获取类的信息并创建对象。推荐使用Constructor.newInstance()示例importjava.lang.reflect.Constructor;publicclassTest{publicstaticvoidmain(String[]args)throwsException{ClassPersonclazzPerson.class;ConstructorPersonconstructorclazz.getDeclaredConstructor(String.class);Personpersonconstructor.newInstance(李四);person.sayHello();}}输出有参构造方法执行了 你好我是李四代码解释如下。首先获取Person的Class对象ClassPersonclazzPerson.class;然后获取参数为String的构造方法ConstructorPersonconstructorclazz.getDeclaredConstructor(String.class);最后通过构造方法创建对象Personpersonconstructor.newInstance(李四);如果要调用无参构造方法可以写ConstructorPersonconstructorPerson.class.getDeclaredConstructor();Personpersonconstructor.newInstance();为什么需要反射创建对象因为有些场景在编写代码时并不知道最终要创建哪个类。例如配置文件中写着com.example.service.UserService程序运行时读取这个类名再动态创建对象。很多框架内部都大量使用了反射例如Spring Spring Boot MyBatis Hibernate JUnit JacksonSpring 扫描到一个带有Service注解的类后可以通过反射创建它的对象并交给 IoC 容器管理。特点可以动态决定创建哪个类 可以调用无参或有参构造方法 适合框架和底层工具开发 代码比 new 复杂 反射调用通常比直接 new 慢。在现代 Java 中通过反射创建对象时通常推荐使用Constructor.newInstance()。四、方式三使用 Class.newInstance()以前还可以通过Class对象的newInstance()方法创建对象PersonpersonPerson.class.newInstance();或者Class?clazzClass.forName(Person);Personperson(Person)clazz.newInstance();这段代码会调用Person的无参构造方法。但是这种方式存在明显限制只能调用无参构造方法 异常处理不够清晰 无法灵活选择构造方法 该方法已经被废弃。因此现在不建议继续使用clazz.newInstance();推荐改成PersonpersonPerson.class.getDeclaredConstructor().newInstance();也就是说Class.newInstance()可以作为面试知识点了解但新项目中应该使用Constructor.newInstance()。五、方式四使用 clone() 克隆对象clone()的作用不是从零开始创建一个全新状态的对象而是根据已有对象复制出一个新对象。首先让类实现Cloneable接口classPersonimplementsCloneable{privateStringname;publicPerson(Stringname){this.namename;System.out.println(构造方法执行了);}publicStringgetName(){returnname;}OverridepublicPersonclone()throwsCloneNotSupportedException{return(Person)super.clone();}}使用publicclassTest{publicstaticvoidmain(String[]args)throwsCloneNotSupportedException{Personp1newPerson(王五);Personp2p1.clone();System.out.println(p1p2);System.out.println(p2.getName());}}输出构造方法执行了 false 王五注意构造方法只执行了一次。执行Personp2p1.clone();时并不会再次调用Person的构造方法。同时p1p2结果为false说明p1和p2指向两个不同的对象。clone() 默认是浅拷贝如果Person中包含一个引用类型成员classAddress{Stringcity;}classPersonimplementsCloneable{Stringname;Addressaddress;OverridepublicPersonclone()throwsCloneNotSupportedException{return(Person)super.clone();}}执行Personp2p1.clone();会得到p1 和 p2 是不同的 Person 对象 p1.address 和 p2.address 指向同一个 Address 对象。也就是说super.clone()默认实现的是浅拷贝。如果需要深拷贝还需要继续复制内部对象。特点根据已有对象复制新对象 通常不会调用构造方法 默认是浅拷贝 需要实现 Cloneable 适合复制已有对象状态。六、方式五使用反序列化创建对象序列化是把对象转换成字节数据反序列化则是把字节数据恢复成对象。首先让类实现Serializableimportjava.io.Serializable;classPersonimplementsSerializable{privatestaticfinallongserialVersionUID1L;privateStringname;publicPerson(Stringname){this.namename;System.out.println(构造方法执行了);}publicStringgetName(){returnname;}}把对象序列化到文件importjava.io.FileOutputStream;importjava.io.ObjectOutputStream;PersonpersonnewPerson(赵六);try(ObjectOutputStreamoutputnewObjectOutputStream(newFileOutputStream(person.dat))){output.writeObject(person);}再通过反序列化恢复对象importjava.io.FileInputStream;importjava.io.ObjectInputStream;Personperson;try(ObjectInputStreaminputnewObjectInputStream(newFileInputStream(person.dat))){person(Person)input.readObject();}System.out.println(person.getName());反序列化会根据文件中的数据重新创建一个Person对象。对于普通实现了Serializable的类反序列化时通常不会调用该可序列化类的构造方法。使用场景反序列化常见于读取持久化对象 网络传输 缓存恢复 消息通信 对象深拷贝。不过Java 原生序列化存在性能、安全性和兼容性方面的问题。现代项目中更常见的是使用JSON Protocol Buffers Kryo Avro等格式传输或保存数据。特点根据已有的字节数据恢复对象 通常不会调用当前类的构造方法 类需要实现 Serializable 可能存在安全和版本兼容问题。不要反序列化不可信来源的数据否则可能带来安全风险。七、方式六使用工厂方法获得对象工厂方法是实际开发中非常常见的一种对象获取方式。例如classPerson{privateStringname;privatePerson(Stringname){this.namename;}publicstaticPersoncreate(Stringname){returnnewPerson(name);}}使用PersonpersonPerson.create(小明);表面上没有直接使用new而是通过Person.create()获得对象。不过需要注意工厂方法内部可能仍然使用了newreturnnewPerson(name);因此从 JVM 底层角度看最终可能还是由new创建对象但从调用者角度看对象是通过工厂方法获得的。工厂方法有什么好处1. 方法名更清晰Person.createAdmin();Person.createGuest();Person.fromDatabase(data);比多个含义不清晰的构造方法更容易理解。2. 可以返回缓存对象例如IntegeraInteger.valueOf(100);IntegerbInteger.valueOf(100);Integer.valueOf()可能返回缓存中的已有对象而不是每次都创建新对象。3. 可以返回子类对象AnimalanimalAnimalFactory.create(dog);工厂内部可以根据参数返回newDog()或者newCat()调用者不需要关心具体实现类。4. 可以统一控制创建过程工厂方法可以加入参数校验 缓存 对象池 权限检查 日志记录 依赖注入。常见例子Java 中有很多工厂方法Integer.valueOf(10);List.of(A,B);LocalDate.of(2026,7,12);Optional.of(Java);Executors.newFixedThreadPool(5);特点隐藏对象创建细节 方法名可以表达业务含义 可以返回缓存对象或子类对象 有利于降低代码耦合 内部不一定每次都创建新对象。严格来说“通过工厂方法获得对象”不一定意味着每次都创建了新对象因为它可能返回已有对象。八、使用 Unsafe 创建对象Java 底层还存在一种特殊方式通过Unsafe分配对象。概念上可以写成Personperson(Person)unsafe.allocateInstance(Person.class);它可以直接为对象分配内存但不会正常调用构造方法。Unsafe属于底层内部 API可能破坏 Java 的封装性和对象初始化规则一般业务开发中不应该使用。它更可能出现在JVM 底层工具 高性能框架 序列化框架 代理框架 特殊测试场景。对于初学者只需要知道这种方式存在即可不建议实际使用。九、这些方式是否都会调用构造方法不同创建方式对构造方法的调用情况不同。创建方式是否调用构造方法常见用途new会普通对象创建Constructor.newInstance()会反射、框架Class.newInstance()会调用无参构造旧式反射不推荐clone()通常不会复制已有对象反序列化当前可序列化类通常不会恢复对象工厂方法取决于内部实现封装创建逻辑Unsafe.allocateInstance()不会底层框架这是面试中经常考察的一个重点使用new和反射调用构造器会执行构造方法使用clone()和普通反序列化恢复当前类对象时通常不会调用该类构造方法。十、创建对象和获得对象有什么区别严格来说有些方式是“真正创建新对象”有些方式只是“获得一个对象”。例如IntegernumberInteger.valueOf(100);valueOf()可能返回缓存中的已有对象因此不保证一定创建新对象。再例如 SpringUserServiceuserServiceapplicationContext.getBean(UserService.class);这里是从 Spring 容器获取对象对象可能早已创建完成并不是此时才创建。因此下面两种说法存在细微区别创建对象明确产生一个新的对象实例 获得对象拿到一个对象引用可能是新对象也可能是已有对象。不过在初级面试题中工厂方法、Spring 容器等方式经常也会被归入“对象创建方式”进行讨论。十一、实际开发应该选择哪种方式普通业务对象优先使用newPerson();代码直观、简单。框架动态创建对象使用反射clazz.getDeclaredConstructor().newInstance();复制已有对象可以使用拷贝构造方法 clone() 手动字段复制。相比clone()很多项目更喜欢使用拷贝构造方法因为逻辑更加明确PersoncopiednewPerson(original);从文件、缓存或网络恢复对象可以使用反序列化但实际项目中通常优先考虑 JSON、Protobuf 等方案。隐藏复杂创建逻辑使用工厂方法PersonpersonPersonFactory.create(type);十二、常见面试问题1. Java 创建对象有哪些方式可以回答Java 创建或获得对象的常见方式包括使用 new 关键字、使用反射调用构造方法、通过 clone() 克隆对象、通过反序列化恢复对象以及通过静态工厂方法或工厂模式获得对象。其中Class.newInstance() 已经被废弃反射创建对象推荐使用 Constructor.newInstance()。2. 哪些方式不会调用构造方法可以回答使用 clone() 克隆对象通常不会调用构造方法通过 Java 反序列化恢复当前可序列化类对象时通常也不会调用该类构造方法Unsafe.allocateInstance() 同样不会调用构造方法。3. newInstance() 推荐使用哪一个推荐clazz.getDeclaredConstructor().newInstance();不推荐clazz.newInstance();因为后者已经被废弃并且只能调用无参构造方法。十三、总结Java 中常见的对象创建或获取方式包括1. new最常用会调用构造方法 2. Constructor.newInstance()通过反射调用构造方法 3. Class.newInstance()旧式反射方式已经废弃 4. clone()复制已有对象通常不调用构造方法 5. 反序列化从字节数据恢复对象 6. 工厂方法隐藏创建细节可能创建新对象也可能返回已有对象 7. Unsafe底层特殊方式不建议普通开发使用。初学者最需要掌握的是new 反射 clone 反序列化 工厂方法最后用一句话概括Java 创建对象不只有new还可以通过反射、克隆、反序列化和工厂方法等方式获得对象它们最大的区别在于创建过程是否调用构造方法、是否依赖已有对象以及是否真正生成新的对象实例。
延伸阅读

更多相关文章

2026/10/26 22:28:45

Git bundle 与 tar/zip 备份对比:2种方案性能与完整性实测

Git Bundle 与 Tar/Zip 备份方案深度对比:性能与完整性实测报告在代码版本管理和数据备份领域,Git bundle 和传统的文件系统打包工具(如 tar、zip)是两种截然不同的技术路线。本文将通过 12 项核心指标的系统性测试,揭…

2026/10/27 1:05:14

VS Code C# Dev Kit 1.0 配置指南:5个必装插件与 .NET 8 项目创建实战

VS Code C# Dev Kit 1.0 配置指南:5个必装插件与 .NET 8 项目创建实战微软最新推出的C# Dev Kit扩展包彻底改变了VS Code的.NET开发体验。作为从Visual Studio迁移过来的老用户,我发现这套工具链不仅保留了VS的核心功能,还带来了更轻量高效的…

2026/11/1 2:01:37

1.c++入门篇

1.c中的关键字asmdoifreturntrycontinueautodoubleinlineshorttypedefforbooldynamic_castintsignedtypeidpublicbreakelselongsizeoftypenamethrowcaseenummutablestaticunionwchar_tcatchexplicitnamespacestatic_castunsigneddefaultcharexportnewstructusingfriendclassext…

2026/11/1 2:01:37

《江灯合声》:有可行的分框版,也仍可以选择连续鸣谢

武汉江岸区栎坡合唱团在免费节目册《江灯合声》中,以表格集中鸣谢资助者。各家共同要求改为独立小框,团里仍想保留表格。现有全名与支持事项清楚可见,双方此前未承诺具体排版。我支持保留表格。补充的试排材料让选择更具体:分框能…

2026/11/1 2:01:37

关于“贾子猜想”的数学地位、结构特征与讨论边界

关于“贾子猜想”的数学地位、结构特征与讨论边界摘要 本文对“贾子猜想”进行基于公开表述与现有数学事实的分析。该猜想主张:当正整数 n3m>5(即 n6,9,12,15,…)时,方程x₁ⁿ x₂ⁿ ⋯ xₙⁿ yⁿ不存在正整数解。文章首先…

2026/11/1 2:01:37

启动报Port 8088 was already in use?先查是谁占的

启动报Port 8088 was already in use?先查是谁占的 项目启动报 Port 8088 was already in use,意思很直白:这个端口已经有人占了。 先说原理:端口是"门牌号",一间房只住一个进程 端口就是一台机器上的门牌号…

2026/11/1 2:01:37

担心文档上云?本地运行的办公AI才敢放心用

单位上周开了个会,主题是"AI 提效",散会时领导补了一句:涉及客户资料的文档,不许往云端传。这话一出,会议室里本来跃跃欲试的同事全蔫了——大家平时用的那些在线 AI,文档一上传就不知道存哪儿去…

2026/11/1 1:56:37

华为OD机试真题 新系统 2026-10-28 JavaGoC【社交网络消息转发】

目录 题目 思路 Code 题目 题目内容: 在一个社交网络中,有 N 个用户(编号 0 到 N−1);每个用户都有一个「转发名单」(整数),该数二进制格式中的第 i 位为 1 表示此用户会把消息转发给第 i 个用户。 给定一个整数数组 forwardLists 和一个整数 initialSenders,请…

2026/11/1 0:01:26

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/1 1:01:33

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/1 0:01:26

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/1 1:01:33

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/1 0:01:26

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/1 1:01:33

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑