java中创建对象的方式大致分为四种吧。分别是 1、通过new关键字 2、通过反射机制 3、通过克隆方式 4、通过序列化方式
之前学过单例模式的时候了解到,反射,克隆,序列化等方式会破坏单例模式,因为通过这种方式获取到的对象和原来的对象根本不是同一个。下面我们来检测一下。
这里仅供测试使用,采用了饿汉式的单例模式,本案例未应用多线程,所以这里写的比较简单
Student类
import java.io.Serializable; /** * @author: xuzhi * @date: 2020/10/8 10:45 */ public class Student implements Cloneable, Serializable { private int id; private String name; private final static Student instance=new Student(); 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; } private Student(){ } public static Student getInstance(){ return instance; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } }测试类
import org.junit.Test; import java.io.*; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; /** * @author: xuzhi * @date: 2020/10/8 10:47 */ public class StudentTest { @Test public void test_new(){ System.out.println("=========单例模式============"); Student student=Student.getInstance(); System.out.println("单例模式获取的对象:"+student); } /** * 测试反射创建对象,使用Class类的newInstance()方法 * 构造器私有,此方法暂时忽略 * @throws ClassNotFoundException * @throws IllegalAccessException * @throws InstantiationException */ // @Test public void test_class_newInstance() throws ClassNotFoundException, IllegalAccessException, InstantiationException { Student stuOne = (Student) Class.forName("com.whpu.object.Student").newInstance(); System.out.println(stuOne); Student stuTwo = Student.class.newInstance(); System.out.println(stuTwo); } /** * 测试反射创建对象,使用Constructor类的newInstance()方法 * @throws NoSuchMethodException * @throws IllegalAccessException * @throws InvocationTargetException * @throws InstantiationException */ @Test public void test_constructor_newInstance() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { System.out.println("=========反射机制============"); Constructor<Student> constructor = Student.class.getDeclaredConstructor(); constructor.setAccessible(true); Student student = constructor.newInstance(); System.out.println("反射机制获取的对象"+student); } /** * 使用克隆的方式创建对象 * @throws CloneNotSupportedException */ @Test public void test_clone() throws CloneNotSupportedException { System.out.println("=========克隆方式============"); Student student=Student.getInstance(); System.out.println(student); Student clone = (Student)student.clone(); System.out.println("克隆模式获取对象"+clone); } /** * 通过反序列化来创建对象 */ @Test public void test_serilizable() throws IOException, ClassNotFoundException { System.out.println("=========序列化方式============"); ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("Student.txt")); Student student=Student.getInstance(); student.setId(5); student.setName("xuzhi"); oos.writeObject(student); System.out.println(student); ObjectInputStream ois = new ObjectInputStream(new FileInputStream("Student.txt")); Student stu =(Student) ois.readObject(); System.out.println(stu.getName()+stu.getId()); System.out.println("序列化获取对象"+stu); } }从结果可以看出,反射,克隆,反序列化的确会破坏单例模式