一、创建实例对象的5种方式
- 通过NEW关键字创建实例对象:new关键字将调用类的有参构造或无参构造来创建实例对象。
- 通过Class.forName("类全路径").newInstance()创建实例对象:默认调用类的无参构造创建实例对象。
- 通过T.class.getConstructors()[0].newInstance()创建实例对象:需要指定某个狗杂器来创建实例对象。
- 通过clone()创建对象:clone()是Object类的一个方法;t.clone()创建一个和t一模一样的对象,包括内容也一样,相当于克隆了一个对象。
- 通过反序列化创建实例对象。
二、浅拷贝
- clone():protected native Object clone() throws CloneNotSupportedException
- 作用:复制对象,产生一个新的实例对象。
- native关键字:被native修饰的方法是以恶搞JAVA调用非Java代码的接口;native常与JNI(Java natvie interface)一起使用。
- 调用对象的clone()方法,必须要对象对应的类实现Cloneable接口,并重写clone()方法。
- 浅拷贝实现
- 通过clone()实现浅拷贝
//1.声明一个类,重写clone方法
public class Person implements Cloneable{
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
//2.通过clone()方法进行浅拷贝
Person p =(Person)Person.class.getConstructors()[0].newInstance();
Person p1 = (Person) p.clone();
//3.浅拷贝特点:
//a.创建一个新对象,然后将当前对象的[非静态字段]复制到该新对象;
//b.如果字段是值类型的,那么对该字段执行复制;
//c.如果该字段是引用类型的话,则复制引用但不复制引用的对象,因此原始对象及其副本引用同一个对象:
//当通过其中一个对象对引用进行了修改,则另一个对象所对应的引用也将被修改。
三、深拷贝
- 深拷贝特点:
- 创建一个新对象,然后将当前对象的非静态字段赋值到该新对象:无论该字段是值类型还是引用类型,都复制独立的一份,即修改气质一个对象的任何内容,不会影响另一个对象。
- 深拷贝对象的每个引用类型属性内部都重写clone()方法。
- 如果引用对象中还有引用对象,则需要依次重写clone()方法。
- 如何实现深拷贝
- 利用序列化实现深拷贝:因为序列化产生的两耳光完全独立的对象,因此物理嵌套多少个引用类型,序列化都能实现深拷贝。
-
public Object deepClone() throws Exception{ // 序列化 ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(this); // 反序列化 ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); return ois.readObject(); }
四、通过第三方框架实现对象复制——可实现两个不同类相同属性的复制
- Apache的BeanUtils:支持类型转换,即两个实例对象的同名属性为不同类型时,支持数据类型范围内进行转换。——不推荐使用。
- Apache的PropertyUtils:不支持类型转换。——推荐低频次下使用。
- Spring的BeanUtils:不支持类型转换。
- Cglib的BeanCopier:不支持类型转换。——推荐高频次下使用。