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创建对象内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java8 Stream对两个 List 遍历匹配数据的优化处理操作

    Java8 Stream对两个 List 遍历匹配数据的优化处理操作

    这篇文章主要介绍了Java8 Stream对两个 List 遍历匹配数据的优化处理操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • 基于@ComponentScan注解的使用详解

    基于@ComponentScan注解的使用详解

    这篇文章主要介绍了@ComponentScan注解的使用详解,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • Java的RocketMq水平扩展及负载均衡详解

    Java的RocketMq水平扩展及负载均衡详解

    这篇文章主要介绍了Java的RocketMq水平扩展及负载均衡详解,RocketMQ是一个分布式具有高度可扩展性的消息中间件,本文旨在探索在broker端,生产端,以及消费端是如何做到横向扩展以及负载均衡的,需要的朋友可以参考下
    2024-01-01
  • Javassist用法详解

    Javassist用法详解

    这篇文章主要介绍了Javassist用法的相关资料,帮助大家更好的理解和学习使用Java,感兴趣的朋友可以了解下
    2021-02-02
  • Mybatis Plus代码生成器(时间管理大师)

    Mybatis Plus代码生成器(时间管理大师)

    这篇文章主要介绍了Mybatis Plus代码生成器(时间管理大师)的相关知识,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-07-07
  • JSP 获取spring容器中bean的两种方法总结

    JSP 获取spring容器中bean的两种方法总结

    这篇文章主要介绍了JSP 获取spring容器中bean的方法总结的相关资料,需要的朋友可以参考下
    2017-05-05
  • java swing 创建一个简单的QQ界面教程

    java swing 创建一个简单的QQ界面教程

    这篇文章主要介绍了java swing 创建一个简单的QQ界面教程,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • Netty解决 TCP 粘包拆包的方法

    Netty解决 TCP 粘包拆包的方法

    处理粘包的唯一方法就是制定应用层的数据通讯协议,通过协议来规范现有接收的数据是否满足消息数据的需要,本文给大家介绍Netty解决 TCP 粘包拆包的方法,需要的朋友一起看看吧
    2021-07-07
  • IDEA 设置 SpringBoot logback 彩色日志的解决方法 附配置文件

    IDEA 设置 SpringBoot logback 彩色日志的解决方法 附配置文件

    这篇文章主要介绍了IDEA 设置 SpringBoot logback 彩色日志(附配置文件)的操作方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-12-12
  • java循环结构、数组的使用小结

    java循环结构、数组的使用小结

    这篇文章主要介绍了java循环结构、数组的使用小结,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-09-09

最新评论