标签:ringbuf his 硬件 throws port protect 序列化 ext this
public class Objcet{
protected native Object clone() throws CloneNotSupportedException();
}
由源码可知。
//cloneTest.java
package com.testbase.clone;
public class cloneTest {
public static void main(String[] args){
// 虽然我们已经实现了Cloneable接口,不会产生异常
// 但是编译器并不知道,会报错,所以这里要捕获异常
try
{
Employee tobin = new Employee(30000);
int salary = tobin.getSalary();
System.out.println(salary);
Employee shengsheng = tobin.clone();
int shengSalary = shengsheng.getSalary();
System.out.println(shengSalary);
}
catch (CloneNotSupportedException e)
{
e.printStackTrace();
}
}
}
//Employee.java
package com.testbase.clone;
public class Employee implements Cloneable
{
private int salary;
public Employee()
{
}
public Employee(int asalary)
{
salary = asalary;
}
@Override
public Employee clone() throws CloneNotSupportedException
{
Employee cloned = (Employee) super.clone();
return cloned;
}
public int getSalary() {
return salary;
}
}
package com.testbase.clone;
public class Employee implements Cloneable
{
private int salary;
public Employee()
{
}
public Employee(int asalary)
{
salary = asalary;
}
// @Override
// public Employee clone() throws CloneNotSupportedException
// {
// Employee cloned = (Employee) super.clone();
// return cloned;
// }
public int getSalary() {
return salary;
}
public static void main(String[] args){
try
{
Employee tobin = new Employee(30000);
int salary = tobin.getSalary();
System.out.println(salary);
Object shengsheng = tobin.clone(); //这里不能强制类型转换
int shengSalary = shengsheng.getSalary();//这里报错,因为Object没有getSalary方法
System.out.println(shengSalary);
}
catch (CloneNotSupportedException e)
{
e.printStackTrace();
}
}
}
浅拷贝:拷贝引用,但是不拷贝引用指向的对象,对拷贝引用的对象进行修改,两份拷贝都会被修改。如果源对象和浅拷贝对象所共享的子对象都是不可变的,那么这种共享就是安全的。比如String类。或者在对象的生命周期内,子对象一直包含着不变的常量,没有更改器方法会改变它,也没有方法会生成它的引用,这种情况同样是安全的。
深拷贝:可能会更改的子对象也进行了拷贝。要进行深拷贝,需要一层层地重写clone方法。
int[] a = {1,2,3,4};
int[] cloned = a.clone();
cloned[0]=11;
1.为什么进行拷贝
2.深拷贝和浅拷贝的区别
3.String克隆的特殊性在那里?StringBuffer和StringBuilder呢?
4.实现对象克隆的常见方式有哪些,具体怎么做?
常用的方式有三种。
代码,主要是第2和第3个方法。
通过实现 Cloneable 接口并重写 Object 类的 clone() 方法实现浅克隆做法:Object 类中 clone 方法的默认实现最终是一个 native 方法(如果 clone 类没有实现 Cloneable 接口并调用了 Object 的 clone 方法就会抛出 CloneNotSupportedException 异常,因为 clone 方法默认实现中有使用 instanceof 进行接口判断),相对来说效率高些,默认实现是先在内存中开辟一块和原始对象一样的空间,然后原样拷贝原始对象中的内容,对基本数据类型就是值复制,而对非基本类型变量保存的仅仅是对象的引用,所以会导致 clone 后的非基本类型变量和原始对象中相应的变量指向的是同一个对象。
浅拷贝。
class Employee implements Clonealbe{
public Employee clone() throws CloneNotSupportedException
{
return (Employee) super.clone();
}
}
深拷贝
class Employee implements Clonealbe{
public Employee clone() throws CloneNotSupportedException
{
Employee cloned = (Employee) super.clone();
cloned.hireDay = (Date) hireDay.clone();
return cloned();
}
}
通过Serializable接口并用对象的序列化和反序列化来实现真正的深拷贝。(还未学到)
class CloneUtil {
public static <T extends Serializable> T clone(T obj) {
T cloneObj = null;
try {
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
objOut.writeObject(obj);
objOut.close();
ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
ObjectInputStream objIn = new ObjectInputStream(byteIn);
cloneObj = (T) objIn.readObject();
objIn.close();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return cloneObj;
}
}
class InfoBean implements Serializable {
public String name;
public int age;
}
class PeopleBean implements Serializable {
public String vipId;
public InfoBean infoBean;
public Object clone() {
return CloneUtil.clone(this);
}
}
参考文章:
https://www.cnblogs.com/gw811/archive/2012/10/07/2712252.html
https://blog.csdn.net/qq_26857649/article/details/84316081
标签:ringbuf his 硬件 throws port protect 序列化 ext this
原文地址:https://www.cnblogs.com/zuotongbin/p/11723346.html