Java创建对象的常见方式技术指南
目录
- 1、简述
- 2、创建对象
- 2.1 使用 new 关键字(最常见)
- 2.2 使用反射 Class.newInstance()(不推荐)
- 2.3 使用反射 Constructor.newInstance()(推荐反射方式)
- 2.4 使用 clone() 方法(浅拷贝)
- 2.5 使用反序列化(从字节流创建)
- 2.6 使用对象工厂(工厂模式)
- 2.7 使用第三方库:如 CGLIB、Objenesis
- 2.8 总结对比
- 3、结语
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();
特点:
- 克隆一个已存在的对象,属于对象复制而非创建全新www.devze.com结构。
- 默认是浅拷贝,若包含引用类型字段需手动实现深拷贝。
- 需要实现 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(jsnew 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() | ❌ 否(复制) | ⚠️ 慎用 | 对象拷贝、实现原型模式 |
反序列化 | ❌ 否 | ⚠️ 慎用 | 网络传输、缓存恢复 |
工厂方法 | ✅ 是 | ✅ 常用 | 面向接口编程、统一对象创建入口 |
Ophpbjenesis / 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创建对象内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.cppcandroidns.com)!
精彩评论