首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >重学Java基础篇—Java对象创建的7种核心方式详解

重学Java基础篇—Java对象创建的7种核心方式详解

原创
作者头像
Remember_Ray
发布2025-03-18 10:28:00
发布2025-03-18 10:28:00
2250
举报
文章被收录于专栏:重学Java重学Java

一、基础创建方式

1.1 new关键字(最常用)

代码语言:java
复制
// 标准对象实例化
Person person = new Person();

特点

  • 直接调用类的构造方法
  • 需要明确的类定义
  • 编译时类型检查

1.2 反射机制

代码语言:java
复制
// 使用Class.newInstance()
Class<?> clazz = Class.forName("com.example.Person");
Person person = (Person) clazz.newInstance();

// 使用Constructor.newInstance()
Constructor<Person> constructor = Person.class.getDeclaredConstructor();
Person person = constructor.newInstance();

对比

方式

是否需要无参构造

能否调用私有构造

异常处理

Class.newInstance()

✅ 必须

包裹在反射异常中

Constructor.newInstance()

支持任意参数构造

✅ 通过setAccessible(true)

直接抛出InvocationTargetException


二、对象复用技术

2.1 克隆(Clone)

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

// 深拷贝示例
class Address implements Cloneable {
    String city;
    
    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

class DeepPerson implements Cloneable {
    Address address;
    
    @Override
    public Object clone() throws CloneNotSupportedException {
        DeepPerson cloned = (DeepPerson) super.clone();
        cloned.address = (Address) address.clone();
        return cloned;
    }
}

2.2 反序列化

代码语言:java
复制
// 序列化对象
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.dat"))) {
    oos.writeObject(new Person("Alice", 30));
}

// 反序列化创建新对象
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.dat"))) {
    Person restoredPerson = (Person) ois.readObject();
}

注意事项

  1. 必须实现Serializable接口
  2. 显式定义serialVersionUID防止版本不一致问题
  3. 反序列化不会调用构造方法

三、设计模式应用

3.1 工厂方法模式

代码语言:java
复制
// 汽车工厂示例
interface Car {
    void drive();
}

class Sedan implements Car {
    public void drive() { System.out.println("驾驶轿车"); }
}

class SUV implements Car {
    public void drive() { System.out.println("驾驶SUV"); }
}

class CarFactory {
    public static Car createCar(String type) {
        switch(type) {
            case "sedan": return new Sedan();
            case "suv"  : return new SUV();
            default     : throw new IllegalArgumentException();
        }
    }
}

// 使用示例
Car myCar = CarFactory.createCar("suv");

3.2 建造者模式

代码语言:java
复制
// 复杂对象创建
class Computer {
    private String cpu;
    private String ram;
    
    private Computer(Builder builder) {
        this.cpu = builder.cpu;
        this.ram = builder.ram;
    }
    
    public static class Builder {
        private String cpu;
        private String ram;
        
        public Builder cpu(String cpu) {
            this.cpu = cpu;
            return this;
        }
        
        public Builder ram(String ram) {
            this.ram = ram;
            return this;
        }
        
        public Computer build() {
            return new Computer(this);
        }
    }
}

// 使用示例
Computer pc = new Computer.Builder()
                        .cpu("i7")
                        .ram("32GB")
                        .build();

四、高级创建技术

4.1 静态工厂方法

代码语言:java
复制
// JDK中的经典实现
public final class LocalDateTime {
    public static LocalDateTime now() {
        // 实际实现逻辑
    }
    
    public static LocalDateTime of(int year, int month, int day, int hour, int minute) {
        // 参数校验和构造逻辑
    }
}

// 使用示例
LocalDateTime meetingTime = LocalDateTime.of(2023, 12, 25, 14, 30);

4.2 Lambda表达式创建

代码语言:java
复制
// 函数式接口实例化
Runnable task = () -> System.out.println("执行任务");
Comparator<String> lengthComparator = (s1, s2) -> s1.length() - s2.length();

// 等效匿名内部类
Runnable oldTask = new Runnable() {
    @Override
    public void run() {
        System.out.println("传统实现方式");
    }
};

五、框架级对象创建

5.1 Spring IOC容器

代码语言:xml
复制
<!-- XML配置方式 -->
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource">
    <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/mydb"/>
    <property name="username" value="root"/>
</bean>
代码语言:java
复制
// 注解配置方式
@Configuration
public class AppConfig {
    @Bean
    public DataSource dataSource() {
        return new HikariDataSource(config);
    }
}

六、创建方式对比

创建方式

适用场景

优点

缺点

new关键字

简单对象直接创建

直观高效

耦合度高

反射机制

动态加载类/框架开发

灵活性强

性能开销大

工厂方法

多态对象创建

解耦创建逻辑

增加类复杂度

建造者模式

复杂参数对象

参数灵活可读性好

代码量较大

克隆

对象复制场景

快速复制

深拷贝实现复杂

依赖注入

企业级应用

集中管理依赖关系

需要框架支持


七、注意事项

  1. 反射创建
    • 需要处理InstantiationException
    • 可能绕过访问权限检查(使用setAccessible(true)
    • 性能比直接new低约50倍(需缓存Constructor)
  2. 克隆陷阱
    • Object.clone()执行浅拷贝
    • 数组元素是引用类型时需特别注意
    • 替代方案:使用复制构造器或序列化实现深拷贝
  3. 反序列化安全
    • 避免反序列化不可信来源的数据
    • 使用readObject()方法进行输入验证
    • 考虑使用ObjectInputFilter
  4. 框架使用原则
    • Spring Bean默认单例模式
    • 合理选择Bean作用域(prototype/request/session)
    • 避免循环依赖

八、扩展知识接口

动态代理对象创建

代码语言:java
复制
interface Subject {
    void request();
}

class RealSubject implements Subject {
    public void request() {
        System.out.println("真实请求");
    }
}

class DynamicProxyHandler implements InvocationHandler {
    private Object target;
    
    public DynamicProxyHandler(Object target) {
        this.target = target;
    }
    
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("前置处理");
        Object result = method.invoke(target, args);
        System.out.println("后置处理");
        return result;
    }
}

// 创建代理对象
Subject proxyInstance = (Subject) Proxy.newProxyInstance(
    RealSubject.class.getClassLoader(),
    new Class[]{Subject.class},
    new DynamicProxyHandler(new RealSubject())
);

Unsafe类绕过构造方法

代码语言:java
复制
// 危险操作示例(仅作了解,实际不推荐使用)
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
Unsafe unsafe = (Unsafe) theUnsafe.get(null);

Person person = (Person) unsafe.allocateInstance(Person.class);

注意

  • 完全跳过构造方法执行
  • 可能导致对象状态不一致
  • 需要Java内部权限
  • 实际开发中禁止使用

九、最佳实践建议

  1. 优先选择最简单的方式:能用new直接创建时不要过度设计
  2. 复杂对象使用建造者模式提高可读性
  3. 框架开发多用工厂方法实现扩展性
  4. 需要对象复用时考虑原型模式
  5. 企业级应用统一使用依赖注入
  6. 动态场景合理运用反射机制但要控制使用范围

根据具体业务需求选择合适的对象创建方式,在灵活性与性能之间找到最佳平衡点。对于核心高频创建的对象,建议进行性能压测。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、基础创建方式
    • 1.1 new关键字(最常用)
    • 1.2 反射机制
  • 二、对象复用技术
    • 2.1 克隆(Clone)
    • 2.2 反序列化
  • 三、设计模式应用
    • 3.1 工厂方法模式
    • 3.2 建造者模式
  • 四、高级创建技术
    • 4.1 静态工厂方法
    • 4.2 Lambda表达式创建
  • 五、框架级对象创建
    • 5.1 Spring IOC容器
  • 六、创建方式对比
  • 七、注意事项
  • 八、扩展知识接口
    • 动态代理对象创建
    • Unsafe类绕过构造方法
  • 九、最佳实践建议
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档