Java创建对象的常见方式技术指南

 更新时间:2025年06月24日 09:02:10   作者:拾荒的小海螺  
在 Java 开发中,对象是一切面向对象编程的基础,Java 提供了多种方式来创建对象,不同方式背后有不同的应用场景与运行机制,下面哦我们就来深入了解下吧

1、简述

在 Java 开发中,“对象”是一切面向对象编程的基础。Java 提供了多种方式来创建对象,不同方式背后有不同的应用场景与运行机制。理解这些方法,对于提升系统性能、掌握底层机制都有重要价值。

2、创建对象

2.1 使用 new 关键字(最常见)

示例代码:

public class User {
    String name;
}

​​​​​​​User user = new User();

说明:

  • 最常见、最直观的方式。
  • 会调用构造方法,分配内存并初始化对象。
  • 编译期类型安全,适用于绝大多数场景。

2.2 使用反射 Class.newInstance()(不推荐)

示例代码:

Class<?> clazz = Class.forName("com.example.User");
User user = (User) clazz.newInstance();

注意事项:

  • 要求类必须有无参构造方法。
  • 在 Java 9 后被标记为过时(deprecated),建议使用 getDeclaredConstructor().newInstance() 替代。
  • 会抛出 InstantiationException、IllegalAccessException。

2.3 使用反射 Constructor.newInstance()(推荐反射方式)

示例代码:

Constructor<User> constructor = User.class.getDeclaredConstructor();
constructor.setAccessible(true);
User user = constructor.newInstance();

特点:

  • 支持调用私有构造方法。
  • 更灵活、安全(可以指定构造函数参数)。
  • 常用于依赖注入、框架内部如 Spring、MyBatis。

2.4 使用 clone() 方法(浅拷贝)

示例代码:

public class User implements Cloneable {
    String name;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
// 使用
User user1 = new User();
user1.name = "Tom";
User user2 = (User) user1.clone();

特点:

  • 克隆一个已存在的对象,属于对象复制而非创建全新结构。
  • 默认是浅拷贝,若包含引用类型字段需手动实现深拷贝。
  • 需要实现 Cloneable 接口,否则抛出 CloneNotSupportedException。

2.5 使用反序列化(从字节流创建)

示例代码:

// 序列化
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("user.ser"));
out.writeObject(user);

// 反序列化
ObjectInputStream in = new ObjectInputStream(new FileInputStream("user.ser"));
User user2 = (User) in.readObject();

特点:

  • 常用于网络传输、缓存存储等场景。
  • 类必须实现 Serializable 接口。
  • 会跳过构造方法的调用(绕过 init 阶段)。

2.6 使用对象工厂(工厂模式)

示例代码:

public class UserFactory {
    public static User createUser(String name) {
        User user = new User();
        user.name = name;
        return user;
    }
}

特点:

  • 封装对象创建逻辑,便于集中管理。
  • 工厂模式是实际开发中常用设计模式之一。
  • Spring 中的 BeanFactory / ApplicationContext 就是这种思想。

2.7 使用第三方库:如 CGLIB、Objenesis

CGLIB 动态代理创建对象(无构造函数调用)

Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(User.class);
enhancer.setCallback(new NoOp() {});
User proxyUser = (User) enhancer.create();

Objenesis

Objenesis objenesis = new ObjenesisStd();
User user = objenesis.newInstance(User.class);

特点:

  • 用于创建不调用构造函数的对象(绕过 new、反射等限制)。
  • Spring、Mockito、Hibernate 等底层使用场景广泛。
  • 不适合日常业务开发,更多用于框架底层实现。

2.8 总结对比

方式是否调用构造函数是否常用应用场景
new✅ 是✅ 常用普通对象创建
Class.newInstance()✅ 是❌ 已过时框架反射,旧代码中偶见
Constructor.newInstance()✅ 是✅ 推荐Spring、框架依赖注入
clone()❌ 否(复制)⚠️ 慎用对象拷贝、实现原型模式
反序列化❌ 否⚠️ 慎用网络传输、缓存恢复
工厂方法✅ 是✅ 常用面向接口编程、统一对象创建入口
Objenesis / CGLIB❌ 否❌ 框架级Spring、Mock 框架底层、ORM 动态代理

实践建议

日常开发:首选 new 或工厂方法,代码清晰,易维护。

框架开发:选择反射 Constructor.newInstance() 或 Objenesis。

对象复制:优先考虑手动复制或使用库如 Apache Commons Lang 的 SerializationUtils,避免使用 clone()。

性能敏感:避免使用反序列化方式,风险高、开销大。

3、结语

Java 提供了多种方式创建对象,不同方式各有适用场景。掌握它们不仅有助于写出更灵活的代码,也有助于深入理解如 Spring、MyBatis、Dubbo 等优秀框架的实现原理。推荐大家多动手实践,如自己实现一个对象工厂,或基于反射构建简单容器,进一步巩固理解。

如果你想,我可以继续提供以下内容:

  • 示例源码项目结构(含反射、clone、Objenesis等示例)
  • 对比几种方式的创建性能(Benchmark)
  • 与 Spring Bean 创建过程的对应关系

到此这篇关于Java创建对象的常见方式技术指南的文章就介绍到这了,更多相关Java创建对象内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • mybatis-generator-gui根据需求改动示例

    mybatis-generator-gui根据需求改动示例

    这篇文章主要为大家介绍了mybatis-generator-gui根据需求改动示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • Caused by: java.io.IOException: DerInputStream.getLength(): lengthTag=111

    Caused by: java.io.IOException: DerInputStrea

    这篇文章主要介绍了Caused by: java.io.IOException: DerInputStream.getLength(): lengthTag=111, too big,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-10-10
  • java实现录音播放功能

    java实现录音播放功能

    这篇文章主要为大家详细介绍了java实现录音播放功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • 简单了解Spring Boot及idea整合jsp过程解析

    简单了解Spring Boot及idea整合jsp过程解析

    这篇文章主要介绍了简单了解Spring Boot及idea整合jsp过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • Docker搭建前端Java的开发环境详解

    Docker搭建前端Java的开发环境详解

    相信每个人入职第一天就是搭建本地开发环境,因为我司用的是java,看见了多年不见的eclipse的图标出现我的电脑上,我是难过的。后来知道并不是我一个人有此感受。这篇文章是为了解决前后端开发没有彻底分离的坑,详细的给大家介绍了利用Docker搭建前端Java的开发环境。
    2016-10-10
  • mybatis-generator自动生成dao、mapping、bean配置操作

    mybatis-generator自动生成dao、mapping、bean配置操作

    这篇文章主要介绍了mybatis-generator自动生成dao、mapping、bean配置操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • SpringBootTest--踩坑错误的解决

    SpringBootTest--踩坑错误的解决

    这篇文章主要介绍了SpringBootTest--踩坑错误的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • Java多线程同步的几种常见方法

    Java多线程同步的几种常见方法

    在 Java 中,多线程同步是确保多个线程在访问共享资源时不会发生竞争和冲突的机制,Java 提供了多种方式来实现线程同步,以下是 Java 中常见的几种同步方法,需要的朋友可以参考下
    2025-05-05
  • IDEA全量替换一次性解决旧项目并将所有文件换行符改为LF问题

    IDEA全量替换一次性解决旧项目并将所有文件换行符改为LF问题

    这篇文章主要介绍了IDEA全量替换一次性解决旧项目并将所有文件换行符改为LF问题,非常不错,具有一定的参考借鉴价值,需要的朋友参考下
    2019-05-05
  • Java volatile关键字原理剖析与实例讲解

    Java volatile关键字原理剖析与实例讲解

    volatile是Java提供的一种轻量级的同步机制,Java 语言包含两种内在的同步机制:同步块(或方法)和 volatile 变量,本文将详细为大家总结Java volatile关键字,通过详细的代码示例给大家介绍的非常详细,需要的朋友可以参考下
    2023-07-07

最新评论