将会列举5种方法去创建 Java 对象,以及他们如何与构造函数交互,并且会有介绍如何去使用这些方法的示例。
作为一个 Java 开发人员,我们每天都会创建大量的 Java 对象,但是我们通常会使用依赖管理系统去创建这些对象,例如 Spring 。然而,我们可以有更多的方式去创建对象,让我们一起在文章中去学习这些方法吧。
这里列举在 Java 中创建对象的五种方式,下面将介绍它们的示例,以及创建对象的行的字节码。
1.使用 new 关键字 | 构造函数会被调用 |
2.使用 Class 类的 newInstance() | 构造函数会被调用 |
3.使用 Constructor 类的 newInstance() | 构造函数会被调用 |
4.使用 clone() 方法 | 无构造函数调用 |
5.使用 序列化 | 无构造函数调用 |
如果您将执行最后给出的程序,您将看到方法1、2、3使用构造函数创建对象,而4、5没有调用构造函数创建对象。
1.使用 new 关键字
这是创建一个对象最通用、常规的方法,同时也是最简单的方式。通过使用此方法,我们可以调用任何要调用的构造函数(默认使用无参构造函数)。
Employee emp1 = new Employee();
2.使用 Class 类的 newInstance()
我们能够使用 Class 类的 newInstance() 方法创建对象。这个 newInstance() 方法将调用无参构造方法去创建一个对象。
在下述代码中,我们通过调用 newInstance() 去创建一个对象:
Employee emp2 = (Employee) Class.forName("org.programming.mitra.exercises.Employee").newInstance();
或者:
Employee emp2 = Employee.class.newInstance();
3.使用 Constructor 类的 newInstance()
与 Class 类中的 newInstance() 方法相似,在此我们将使用 java.lang.reflect.Constructor 类中的 newInstance() 方法创建对象。通过使用这个 newInstance() 方法我们能够调用有参构造函数和私有构造函数。
Constructor constructor = Employee.class.getConstructor();
Employee emp3 = constructor.newInstance();
这两个 newInstance() 方法都被称为创建对象的反射方法。实际上, Class 类的 newInstance() 方法内部使用 Constructor 类的 newInstance() 方法。这就是为什么后者更受欢迎,并且也被 Spring、Hibernate、Structs 等不同的框架所使用的原因。
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(这些方法直接处理对象的创建),但第一个方法转换为两个调用,一个是new,另一个是invokespecial(对构造函数的调用)。
示例
创建对象的 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 int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Employee other = (Employee) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public String toString() {
return "Employee [name=" + 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.使用 new 关键字
Employee emp1 = new Employee();
emp1.setName("Naresh");
System.out.println(emp1 + ", hashcode : " + emp1.hashCode());
// 2.使用 Class 类的 newInstance()
Employee emp2 = (Employee) Class.forName("org.programming.mitra.exercises.Employee")
.newInstance();
// Or we can simply do this
// Employee emp2 = Employee.class.newInstance();
emp2.setName("Rishi");
System.out.println(emp2 + ", hashcode : " + emp2.hashCode());
//3.使用 Constructor 类的 newInstance()
Constructor<Employee> constructor = Employee.class.getConstructor();
Employee emp3 = constructor.newInstance();
emp3.setName("Yogesh");
System.out.println(emp3 + ", hashcode : " + emp3.hashCode());
// 4.使用 Clone() 方法
Employee emp4 = (Employee) emp3.clone();
emp4.setName("Atul");
System.out.println(emp4 + ", hashcode : " + emp4.hashCode());
// 使用序列化
// Serialization
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("data.obj"));
out.writeObject(emp4);
out.close();
//Deserialization
ObjectInputStream in = new ObjectInputStream(new FileInputStream("data.obj"));
Employee emp5 = (Employee) in.readObject();
in.close();
emp5.setName("Akash");
System.out.println(emp5 + ", hashcode : " + emp5.hashCode());
}
}
此程序执行将有以下输出:
Employee Constructor Called...
Employee [name=Naresh], hashcode : -1968815046
Employee Constructor Called...
Employee [name=Rishi], hashcode : 78970652
Employee Constructor Called...
Employee [name=Yogesh], hashcode : -1641292792
Employee [name=Atul], hashcode : 2051657
Employee [name=Akash], hashcode : 63313419
原文:https://dzone.com/articles/5-different-ways-to-create-objects-in-java-with-ex