【转载】创建对象的5种方法
创建对象的方式 | 是否调用了构造器 |
new关键字 | 是 |
Class类的newInstance方法 | 是 |
Constructor类的newInstance方法 | 是 |
Clone方法 | 否 |
反序列化 | 否 |
测试类Teacher
import java.io.Serializable; public class Teacher implements Serializable{ private static final long serialVersionUID = 8363559040208136513L; public Teacher() { System.out.println("老师的无参构造方法"); // TODO Auto-generated constructor stub } }
测试类Student
import java.io.Serializable; import java.util.Date; public class Student implements Cloneable,Serializable{ private static final long serialVersionUID = -3347859007645821784L; private Long id; private String name; private Integer age; private Date birthday; private Teacher teacher; public Student() { System.out.println("默认构造方法"); } public Student(Long id) { System.out.println("id构造方法"); this.id = id; } public Student(Long id, String name, Integer age, Date birthday, Teacher teacher) { System.out.println("全属性构造方法"); this.id = id; this.name = name; this.age = age; this.birthday = birthday; this.teacher = teacher; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public Teacher getTeacher() { return teacher; } public void setTeacher(Teacher teacher) { this.teacher = teacher; } @Override public String toString() { return "Student [id=" + id + ", name=" + name + ", age=" + age + ", birthday=" + birthday + ", teacher=" + teacher + "]"; } @Override protected Object clone() throws CloneNotSupportedException { // TODO Auto-generated method stub return super.clone(); } }
一、new关键字创建对象,是最常见的创建对象的方式,可以调用任意public构造函数
Student student1 = new Student(100L); System.out.println(student1);
二、 使用Class类的newInstance方法,只能调用默认的无参构造器,其实本质上是调用反射相关类Constructor类的无参newInstance方法。
Student student2 = Student.class.newInstance(); System.out.println(student2);
三、使用Constructor类的newInstance方法,可以调用任意构造器,包括有参无参,公有非公有
Constructor<Student> constructor = Student.class.getConstructor(); Student student3 = constructor.newInstance(); Constructor<Student> constructor1 = Student.class.getConstructor(Long.class); Student student4 = constructor1.newInstance(100L);
四、使用Object的clone方法,不会调用任何构造函数,需要实现Cloneable接口,native本地方法实现,JVM新建一个对象,将原对象的内容全部拷贝进去,如果原对象内属性有引用对象,则新的对象的对应属性仍指向该引用对象。
Student student5 = (Student)student1.clone(); student5.setTeacher(new Teacher()); System.out.println(student5.getTeacher().hashCode()); Student student6 = (Student) student5.clone(); System.out.println("student6:"+student6.getTeacher().hashCode());
五、使用反序列化,需要实现Serializable,不调用任何构造器,如果里面属性信息有引用对象,反序列化出的对象内的对应属性引用对象会重新创建(仍然不调用构造器)
ObjectOutputStream oos = null; ByteArrayOutputStream baos = null; ObjectInputStream ois = null; ByteArrayInputStream bais = null; byte[] bs = null; try { //序列化 baos = new ByteArrayOutputStream(); oos = new ObjectOutputStream(baos); oos.writeObject(student6); oos.flush(); bs = baos.toByteArray(); //反序列化 bais = new ByteArrayInputStream(bs); ois = new ObjectInputStream(bais); Student student7 = (Student) ois.readObject(); System.out.println("student7:"+student7.hashCode()); System.out.println("student7:"+student7.getTeacher().hashCode()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }
下面列出测试类的全部代码:
import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; public class CreateObject { public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, CloneNotSupportedException { Student student1 = new Student(100L); System.out.println(student1); Student student2 = Student.class.newInstance(); System.out.println(student2); Constructor<Student> constructor = Student.class.getConstructor(); Student student3 = constructor.newInstance(); Constructor<Student> constructor1 = Student.class.getConstructor(Long.class); Student student4 = constructor1.newInstance(100L); Student student5 = (Student)student1.clone(); student5.setTeacher(new Teacher()); System.out.println(student5.getTeacher().hashCode()); Student student6 = (Student) student5.clone(); System.out.println("student6:"+student6.getTeacher().hashCode()); ObjectOutputStream oos = null; ByteArrayOutputStream baos = null; ObjectInputStream ois = null; ByteArrayInputStream bais = null; byte[] bs = null; try { //序列化 baos = new ByteArrayOutputStream(); oos = new ObjectOutputStream(baos); oos.writeObject(student6); oos.flush(); bs = baos.toByteArray(); //反序列化 bais = new ByteArrayInputStream(bs); ois = new ObjectInputStream(bais); Student student7 = (Student) ois.readObject(); System.out.println("student7:"+student7.hashCode()); System.out.println("student7:"+student7.getTeacher().hashCode()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }