java实例化对象到底有几种方式?超乎你的想象

java实例化对象到底有几种方式?超乎你的想象

  1. 使用new关键字
    这是最常见且最简单的实例化对象的方式。

通过new关键字,可以调用类的构造函数(无论是无参构造函数还是带参数的构造函数)来创建对象。

public class Employee {
private String name;

public Employee() {  
    // 无参构造函数  
}  

public Employee(String name) {  
    this.name = name;  
}  

public void setName(String name) {  
    this.name = name;  
}  

public String getName() {  
    return name;  
}  

public static void main(String[] args) {  
    Employee emp1 = new Employee(); // 使用无参构造函数  
    emp1.setName("张三");  

    Employee emp2 = new Employee("李四"); // 使用带参数的构造函数  
    System.out.println(emp2.getName()); // 输出:李四  
}  

}
2. 使用Class类的newInstance方法
Class类的newInstance方法可以用来动态地创建类的实例。

不过,需要注意的是,从Java 9开始,newInstance方法已被标记为过时(deprecated),推荐使用Class的getDeclaredConstructor()方法与Constructor的newInstance()方法组合使用。

示例代码(Java 9之前):

try {
Class<?> clazz = Class.forName(“Employee”);
Employee emp = (Employee) clazz.newInstance(); // 注意处理异常
emp.setName(“王五”);
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
Java 9及以后推荐方式:

try {
Constructor constructor = Employee.class.getDeclaredConstructor();
Employee emp = constructor.newInstance();
emp.setName(“赵六”);
} catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}

  1. 使用Constructor类的newInstance方法
    与Class类的newInstance方法类似,但这种方式更加灵活,因为它允许你指定具体的构造函数来创建对象。

try {
Constructor constructor = Employee.class.getConstructor(String.class);
Employee emp = constructor.newInstance(“孙七”);
System.out.println(emp.getName()); // 输出:孙七
} catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
4. 使用clone方法
通过clone方法,可以创建一个对象的浅拷贝或深拷贝(取决于类的具体实现)。

要使用clone方法,类必须实现Cloneable接口,并重写Object类的clone方法。

public class Employee implements Cloneable {
// … 其他代码 …

@Override  
protected Object clone() throws CloneNotSupportedException {  
    return super.clone();  
}  

public static void main(String[] args) throws CloneNotSupportedException {  
    Employee emp1 = new Employee("周八");  
    Employee emp2 = (Employee) emp1.clone();  
    System.out.println(emp2.getName()); // 输出:周八  
}  

}
5. 使用序列化和反序列化
通过序列化和反序列化,可以将对象的状态保存到文件中,然后在需要时从文件中恢复对象的状态。

这种方式不调用构造函数。

import java.io.*;

public class Employee implements Serializable {
// … 其他代码 …

public static void main(String[] args) throws IOException, ClassNotFoundException {  
    Employee emp = new Employee("吴九");  

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

    // 反序列化  
    ObjectInputStream in = new ObjectInputStream(new FileInputStream("employee.ser"));  
    Employee empDeserialized = (Employee) in.readObject();  
    System.out.println(empDeserialized.getName()); // 输出:吴九  
    in.close;
}

}
然而,除了上述几种方式外,还有一些间接或特殊的方式可以视为实例化对象的“变种”或特殊应用,

但它们并不直接创建新的对象实例,而是通过其他机制达到类似的效果:

  1. 使用工厂模式:
    工厂模式是一种创建型设计模式,它提供了一种创建对象的最佳方式。

在工厂模式中,我们创建一个工厂类,用于生成某种类型产品的对象。

客户端可以通过调用工厂类的方法来获取所需的对象,而无需知道这些对象是如何被创建和初始化的。

虽然工厂模式本身不直接实例化对象,但它通过封装实例化逻辑来间接控制对象的创建。

public class EmployeeFactory {
public static Employee createEmployee(String type) {
if (“Engineer”.equals(type)) {
return new Engineer(); // Engineer是Employee的子类
} else if (“Manager”.equals(type)) {
return new Manager(); // Manager是Employee的子类
}
return null;
}
}
7. 使用依赖注入(DI)框架:
在依赖注入框架中,对象的创建和依赖关系的建立由框架自动完成,而不是由开发者在代码中显式地创建对象。

例如,在Spring框架中,你可以通过配置文件或注解来声明对某个类的依赖,Spring容器会在运行时自动为你创建这些类的实例,并将它们注入到需要的地方。

@Component
public class MyBean {
// …
}

@Autowired
private MyBean myBean; // Spring会自动注入MyBean的实例
8. 使用单例模式:
单例模式确保一个类仅有一个实例,并提供一个全局访问点。

虽然单例模式不直接创建新的对象实例(在类的整个生命周期内只创建一个实例),但它通过封装对象的创建逻辑来确保对象的唯一性。

在需要时,可以通过单例类的全局访问点来获取这个唯一的实例。

public class Singleton {
private static Singleton instance;

private Singleton() {}  

public static synchronized Singleton getInstance() {  
    if (instance == null) {  
        instance = new Singleton();  
    }  
    return instance;  
}  

}
9. 使用枚举实现单例:
枚举类型在Java中是一种特殊的类,它不能被实例化(除了使用枚举常量)。

因此,可以通过定义一个只包含一个枚举常量的枚举类型来实现单例模式。

这种方式比传统的单例模式更加简洁和安全。

public enum SingletonEnum {
INSTANCE;

// 可以在这里添加方法  

}
需要注意的是,上述方式中的“工厂模式”、“依赖注入框架”和“单例模式”并不直接创建新的对象实例,

而是通过特定的设计模式或框架来管理对象的创建和生命周期。

这些方式在大型应用程序和复杂系统中非常有用,因为它们可以提高代码的可维护性、可扩展性和可测试性。

然而,在简单的应用程序中,直接使用new关键字或反射等直接实例化对象的方式可能更为直接和高效。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

愚公搬程序

你的鼓励将是我们最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值