java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java创建对象方式

一文总结使用Java创建对象的八种方式

作者:程序员大华

这篇文章主要介绍了8种创建对象的方法,包括new关键字、反射机制、clone()方法、反序列化、静态工厂方法、Builder模式、匿名内部类和方法引用,每种方法都有其适用场景和优缺点,需要的朋友可以参考下

昨晚加班的时候,同事来旁边坐着跟我闲聊,不经意间看到屏幕上的new 对象代码,他说:“每次这样new 一个对象感觉好丑,有没有更好的方式方法!”。

我说:“有啊,不过也得看场景,简单的直接用 new 一把梭哈!复杂的再考虑其它的方式”

那有哪些方式呢?下面来分享一下。

1. new关键字

最直接的创建方式

// 就像我们平时说话:"来一辆新车"
Car car = new Car();

// 或者带参数的:"来一辆红色的宝马"
Car bmw = new Car("宝马", "红色");

使用场景:这是最常用的方式,适合90%的日常开发场景。

优点

缺点

2. 反射机制

有时候我们需要在运行时才知道要创建什么类的对象,这时候反射就派上用场了。

// 传统方式:我知道要创建Car
Car car = new Car();

// 反射方式:运行时才知道要创建什么
try {
    Class carClass = Class.forName("com.example.Car");
    Constructor constructor = carClass.getConstructor();
    Car car = (Car) constructor.newInstance();
} catch (Exception e) {
    e.printStackTrace();
}

案例:Spring框架中,当我们配置了@Component注解的类,Spring就是通过反射来创建这些对象的。

// Spring内部大致是这样做的
Class beanClass = loadClass("com.example.UserService");
Object bean = beanClass.getDeclaredConstructor().newInstance();

3. clone()方法

假设你有一个配置好的对象,现在需要另一个一模一样的,这时候clone就很有用。

class UserSettings implements Cloneable {
    private String theme = "dark";
    private int fontSize = 14;
    
    @Override
    public UserSettings clone() {
        try {
            return (UserSettings) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new AssertionError();
        }
    }
}

// 使用clone
UserSettings original = new UserSettings();
UserSettings cloned = original.clone(); // 得到一个完全相同的副本

注意点

4. 反序列化

当我们把对象保存到文件或通过网络传输后,需要重新把它变回对象。

// 对象需要实现Serializable接口
class GameSave implements Serializable {
    private static final long serialVersionUID = 1L;
    private int level;
    private int score;
}

// 保存对象到文件
try (ObjectOutputStream oos = new ObjectOutputStream(
        new FileOutputStream("save.dat"))) {
    oos.writeObject(gameSave);
}

// 从文件读取对象
try (ObjectInputStream ois = new ObjectInputStream(
        new FileInputStream("save.dat"))) {
    GameSave loadedSave = (GameSave) ois.readObject();
    // loadedSave就是原来那个gameSave的副本
}

5. 静态工厂方法

有时候直接new不够表达我们的意图,这时候工厂方法就很有用。

class Color {
    private int red, green, blue;
    
    private Color(int r, int g, int b) {
        this.red = r;
        this.green = g;
        this.blue = b;
    }
    
    // 静态工厂方法:语义更明确
    public static Color fromRGB(int r, int g, int b) {
        return new Color(r, g, b);
    }
    
    public static Color fromHex(String hex) {
        // 解析十六进制颜色码
        return new Color(/* 解析逻辑 */);
    }
    
    public static Color red() {
        return new Color(255, 0, 0);
    }
}

// 使用:这样读起来更自然
Color red = Color.red();
Color custom = Color.fromRGB(255, 128, 0);

优点

6. Builder模式

当对象有很多属性时,构造方法会变得很长很难读,Builder模式来解决!

class Computer {
    private final String cpu;          // 必须
    private final String ram;          // 必须  
    private final String storage;      // 必须
    private final String graphicsCard; // 可选
    private final String monitor;      // 可选
    
    // 私有构造方法,只能通过Builder创建
    private Computer(Builder builder) {
        this.cpu = builder.cpu;
        this.ram = builder.ram;
        this.storage = builder.storage;
        this.graphicsCard = builder.graphicsCard;
        this.monitor = builder.monitor;
    }
    
    public static class Builder {
        // 必须参数
        private final String cpu;
        private final String ram;
        private final String storage;
        
        // 可选参数
        private String graphicsCard = "集成显卡";
        private String monitor = "23寸显示器";
        
        // Builder构造方法包含必须参数
        public Builder(String cpu, String ram, String storage) {
            this.cpu = cpu;
            this.ram = ram;
            this.storage = storage;
        }
        
        // 设置可选参数的方法
        public Builder graphicsCard(String graphicsCard) {
            this.graphicsCard = graphicsCard;
            return this;
        }
        
        public Builder monitor(String monitor) {
            this.monitor = monitor;
            return this;
        }
        
        public Computer build() {
            return new Computer(this);
        }
    }
}

// 使用Builder模式:链式调用,非常清晰
Computer gamingPC = new Computer.Builder("i7", "16GB", "1TB SSD")
    .graphicsCard("RTX 3080")
    .monitor("27寸4K显示器")
    .build();

适用场景

7. 匿名内部类

当我们只需要某个接口的一次性实现时,匿名内部类很方便。

// 创建线程的传统方式
class MyTask implements Runnable {
    @Override
    public void run() {
        System.out.println("执行任务");
    }
}

Runnable task1 = new MyTask();

// 使用匿名内部类:更简洁
Runnable task2 = new Runnable() {
    @Override
    public void run() {
        System.out.println("执行任务");
    }
};

// Java 8以后,可以用lambda表达式进一步简化
Runnable task3 = () -> System.out.println("执行任务");

8. 方法引用

Java 8引入了函数式编程,让对象创建更加优雅。

class Person {
    private String name;
    
    public Person() {
        this.name = "匿名";
    }
    
    public Person(String name) {
        this.name = name;
    }
}

// 方法引用创建对象
Supplier defaultPerson = Person::new;
Function namedPerson = Person::new;

// 使用
Person p1 = defaultPerson.get();      // 调用无参构造
Person p2 = namedPerson.apply("张三"); // 调用有参构造

总结

场景推荐方式理由
日常开发new关键字简单直接,性能好
多参数对象Builder模式可读性好,灵活
需要封装创建逻辑静态工厂方法隐藏实现细节
框架开发反射机制动态性,灵活性
函数式编程方法引用代码简洁,表达力强
创建对象副本clone()方法语义明确,使用方便

简单场景用new,复杂对象用Builder,需要灵活性用工厂方法或反射。

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

您可能感兴趣的文章:
阅读全文