五种方法创建java对象
作为Java
开发人员,我们通常每天都会创建许多对象,但是我们总是使用新的或依赖管理系统(例如Spring
)来创建这些对象。但是,有更多方法可以创建本文中将要研究的对象。
用Java创建对象的共有5种核心方式,下面将以其示例加以说明,然后介绍创建对象的行的字节码。但是,有很多API可以为我们创建对象,但是这些API还将间接使用这5种核心方式之一,例如Spring BeanFactory
。
如果您将执行最后给出的程序,则会看到方法1、2、3使用构造函数创建对象,而4、5没有调用构造函数创建对象。
1.使用新关键字
这是创建对象的最常见和常规的方法,也是一种非常简单的方法。通过使用此方法,我们可以调用要调用的任何构造函数(无参数的构造函数和参数化的)。
Employee emp1 = new Employee();
2.使用Class类的newInstance()方法
我们还可以使用Class
类的newInstance()
方法创建一个对象。此newInstance()
方法调用no-arg
构造函数来创建对象。
我们可以通过newInstance()
通过以下方式创建对象:
Employee emp2 = (Employee) Class.forName("org.programming.mitra.exercises.Employee").newInstance(); Or Employee emp2 = Employee.class.newInstance();
3.使用构造方法类的newInstance()方法
与Class类的newInstance()
方法类似,java.lang.reflect.Constructor
类中有一个newInstance()
方法可用于创建对象。我们还可以使用此newInstance()
方法来调用参数化构造函数和私有构造函数。
Constructor<Employee> constructor = Employee.class.getConstructor(); Employee emp3 = constructor.newInstance();
这两种newInstance()
方法都被称为创建对象的反射方式。实际上,Class
类的newInstance()
方法在内部使用了Constructor
类的newInstance()
方法。这就是为什么最好使用后一种方法,并且也将其用于诸如Spring
,Hibernate,Struts等不同框架的原因。要了解这两种newInstance()方法之间的区别,请阅读使用Example在Java中通过Reflection创建对象。
4.使用clone()方法:
每当我们在任何对象上调用clone()
时,JVM实际上都会为我们创建一个新对象,并将先前对象的所有内容复制到其中。使用clone
方法创建对象不会调用任何构造函数。
要在对象上使用clone()
方法,我们需要实现Cloneable
并在其中定义clone()
方法。
Employee emp4 = (Employee) emp3.clone();
Java克隆是Java社区中最值得探讨的话题,它的确有其缺点,但是在对象完全满足Java克隆的强制条件之前,它仍然是创建任何对象的副本的最流行和最简单的方法。
5.使用反序列化
每当我们序列化然后反序列化一个对象时, JVM就会为我们创建一个单独的对象。在反序列化中,JVM不使用任何构造函数来创建对象。要反序列化对象,我们需要在类中实现Serializable接口。
ObjectInputStream in = new ObjectInputStream(new FileInputStream("data.obj")); Employee emp5 = (Employee) in.readObject();
正如我们在上面的字节码中看到的那样,所有四个方法调用都转换为invokevirtual(这些方法直接处理对象的创建),除了第一个转换为两个调用的方法是一个是新的,另一个是调用特殊的(对构造函数的调用)。
例:
让我们考虑一个我们要为其创建对象的Employee
类:
class Employee implements Cloneable, Serializable { private static final long serialVersionUID = 1L; private String name; public Employee() { System.out.println("Employee Constructor Called..."); } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Employee employee = (Employee) o; return Objects.equals(name, employee.name); } @Override public int hashCode() { return Objects.hash(name); } @Override public String toString() { return String.format("Employee{name='%s'}", name); } @Override public Object clone() { Object obj = null; try { obj = super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return obj; } }
在下面的Java程序中,我们将以所有5种方式创建Employee对象。
public class ObjectCreation { public static void main(String... args) throws Exception { // 1. Using new keyword Employee emp1 = new Employee(); emp1.setName("emp1"); // 2. Using Class class's newInstance() method Employee emp2 = Employee.class.newInstance(); emp2.setName("emp2"); // 3. Using Constructor class's newInstance() method Constructor<Employee> constructor = Employee.class.getConstructor(); Employee emp3 = constructor.newInstance(); emp3.setName("emp3"); // 4. Using clone() method Employee emp4 = (Employee) emp3.clone(); emp4.setName("emp4"); // Serialization try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("data.obj"))) { out.writeObject(emp4); } // 5. Using Deserialization Employee emp5; try (ObjectInputStream in = new ObjectInputStream(new FileInputStream("data.obj"))) { emp5 = (Employee) in.readObject(); emp5.setName("emp5"); } System.out.println(emp1 + ", hashcode : " + emp1.hashCode()); System.out.println(emp2 + ", hashcode : " + emp2.hashCode()); System.out.println(emp3 + ", hashcode : " + emp3.hashCode()); System.out.println(emp4 + ", hashcode : " + emp4.hashCode()); System.out.println(emp5 + ", hashcode : " + emp5.hashCode()); } }
该程序将给出以下输出:
Employee Constructor Called... Employee Constructor Called... Employee Constructor Called... Employee{name='emp1'}, hashcode : 3117192 Employee{name='emp2'}, hashcode : 3117193 Employee{name='emp3'}, hashcode : 3117194 Employee{name='emp4'}, hashcode : 3117195 Employee{name='emp5'}, hashcode : 3117196
完整的Java初级,高级对应的学习路线和资料!专注于java开发。分享java基础、原理性知识、JavaWeb实战、spring全家桶、设计模式、分布式及面试资料、开源项目,助力开发者成长!
欢迎关注微信公众号:码邦主