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);
}
}
从结果可以看出,反射,克隆,反序列化的确会破坏单例模式