原文传送门:https://www.cnblogs.com/wxd0108/p/5685817.html 非常感谢作者
Java 创建对象的五种方式:
方式 | 具体方式 | 是否调用构造函数 |
---|---|---|
new | 使用 new 关键字 | 调用构造函数 |
反射 | 使用 Class 类的 newInstance 方法 | 调用构造函数 |
反射 | 使用 Cosntructor 类的 newInstance 方法 | 调用构造函数 |
克隆 | 使用 clone 方法 | 没有调用构造函数 |
反序列化 | 使用反序列化 | 没有调用构造函数 |
1、使用 new 关键字
最常见、简单的创建对象的方式,可以调用任意的构造函数
Student stu = new Student();
2、使用 Class 类的 newInstance 方法
Student stu = Student.class.newInstance();
3、使用 Constructor 类的 newInstance 方法
Constructor<Student> constructor = Student.class.getConstructor();
Student stu1 = constructor.newInstance();
2 和 3 两种方法就是大家所说的反射,事实上 Class 的 newInstance 方法内部调用 COnstructor 的 newInstance 方法
4、使用 clone 方法
当调用一个对象的 clone 方法时,jvm 就会创建一个新的对象,将前面对象的内容全部拷贝进去,用 clone 方法创建对象并不会调用任何构造函数
要使用 clone 方法,就要首先实现 Cloneable 接口并实现其定义的 clone 方法
Student stu = (Student) stu1.clone();
5、反序列化
先实现 Serializable 接口
ObjectInputStream in = new OnjectInputStream(new FileInputStream("data.obj"));
Student stu = (Student)in.readObject();
6、代码演示
实体类:Student.java
package model;
import java.io.Serializable;
/**
* create by 1311230692@qq.com on 2018/11/14 16:16
* 学生实体类
**/
public class Student implements Cloneable, Serializable {
private int id;
private String name;
private String sex;
public Student() {
System.out.println("Student constructor called...");
}
public Student(int id, String name, String sex) {
this.id = id;
this.name = name;
this.sex = sex;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
CreateObject.java
package function;
import model.Student;
import java.io.*;
import java.lang.reflect.Constructor;
/**
* create by 1311230692@qq.com on 2018/11/14 16:12
* 创建对象
**/
public class CreateObject implements Cloneable, Serializable {
public static void main(String... args) throws Exception{
// 1、使用 new 关键字
Student stu = new Student();
stu.setName("张三");
System.out.println(stu + ", hashcode:" + stu.hashCode());
// 2、使用 Class 类的 newInstance 方法
Student stu1 = (Student)Class.forName("model.Student").newInstance();
stu1.setName("李四");
System.out.println(stu1 + ", hashcode:" + stu1.hashCode());
// 3、使用 Constructor 类的 newInstance 方法
Constructor<Student> constructor = Student.class.getConstructor();
Student stu2 = constructor.newInstance();
stu2.setName("王五");
System.out.println(stu2 + ", hashcode:" + stu2.hashCode());
// 4、使用 clone 方法
Student stu3 = (Student)stu2.clone();
stu3.setName("赵六");
System.out.println(stu3 + ", hashcode:" + stu3.hashCode());
// 5、反序列化
ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("data.obj"));
outputStream.writeObject(stu2);
outputStream.close();
ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("data.obj"));
Student stu4 = (Student)inputStream.readObject();
inputStream.close();
stu4.setName("老七");
System.out.println(stu4 + ", hashcode:" + stu4.hashCode());
}
}
运行结果:
Student constructor called...
Student{id=0, name='张三'}, hashcode:22307196
Student constructor called...
Student{id=0, name='李四'}, hashcode:10568834
Student constructor called...
Student{id=0, name='王五'}, hashcode:21029277
Student{id=0, name='赵六'}, hashcode:24324022
Student{id=0, name='老七'}, hashcode:17033014
Process finished with exit code 0
可以看出,使用 new 和 反射方式创建对象都调用了构造器,而使用克隆、反序列化没有调用构造器