java byte clone_java clone方法例子

吉嘉珍
2023-12-01

// ipconfig | findstr "IPv4"

// soapui cracker:

// json 对象与数组:

package com.qingyuan.server;

import java.io.Serializable;

public class Car implements Serializable

{

/** serialVersionUID */

private static final long serialVersionUID = 4539772529921666906L;

private String brand;

private int price;

public String getBrand()

{

return brand;

}

public void setBrand(String brand)

{

this.brand = brand;

}

public int getPrice()

{

return price;

}

public void setPrice(int price)

{

this.price = price;

}

public Object clone()

{

Car car = null;

try

{

car = (Car) super.clone();

}

catch (CloneNotSupportedException e)

{

e.printStackTrace();

}

return car;

}

}

package com.qingyuan.server;

public class Person implements Cloneable

{

private String name;

private Car car;

public String getName()

{

return name;

}

public void setName(String name)

{

this.name = name;

}

public Car getCar()

{

return car;

}

public void setCar(Car car)

{

this.car = car;

}

public Object clone()

{

Person person = null;

try

{

person = (Person) super.clone();

}

catch (CloneNotSupportedException e)

{

e.printStackTrace();

}

return person;

}

}

package com.qingyuan.server;

import java.io.ByteArrayInputStream;

import java.io.ByteArrayOutputStream;

import java.io.IOException;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

/**

* 深拷贝:最大程度与原对象脱离关系]>

* Java中的拷贝方式分为深拷贝和浅拷贝。简单来说,深拷贝就是把一个对象中的所有值,如果被拷贝对象中有对其他对象的引用,

* 那么这个引用指向的对象本身会被重新创建。浅拷贝和深拷贝类似,但是如果被拷贝对象中有对其他对象的引用,只是这个引用会

* 被拷贝,而不是这个被引用的对象

*

* http://kuangbaoxu.iteye.com/blog/193222

* http://stackoverflow.com/questions/2589741/how-to-effectively-copy-an-array-in-java

* http://stackoverflow.com/questions/18638743/is-it-better-to-use-system-arraycopy-than-a-fast-for-loop-for-copying-array

*

* public static T[] copyOf(U[] original, int newLength, Class extends T[]> newType)

* Object[] foo = new Object[]{...};

* String[] bar = new String[foo.length];

* System.arraycopy(foo, 0, bar, 0, bar.length);

*

* "引用类型的变量"称为指针 [指针变量和该指针变量指向的对象]

* 假设在函数中写了如下这个简单的语句: StringBuffer str = new StringBuffer("newString");

* 1) : new StringBuffer("newString") 在堆里申请了一块内存,把创建好的StringBuffer 对象放入;

* 2) : String str 声明了一个指针,这个指针本事存储在栈上的[因为语句写在函数中],可以用来指向某个StringBuffer 类型的对象,或者换句话说,这个指针可以用来保存某个

* StringBuffer 对象的地址;

* 3) : StringBuffer str = new StringBuffer("newString"); 把刚才申请的那一块内存地址保存为str 的值;

* StringBuffer str2 = str

* 实际上就是把str的地址复制给str2,是地址的复制,StringBuffer对象本身并没有复制。所以两个指针指向的是同一个

*

* 实际上两个指针的值相同,则肯定是指向同一个对象(所以对象内容必定相同)。但是两个内容相同的对象,

* 它们的地址可能不一样(比如克隆出来的多个对象之间,地址就不同)

*

* final常量的问题:

* 针对引用类型变量的final修饰符也是很多人搞混淆的地方。实际上final只是修饰指针的值(也就是限定指针保存的地址不能变)

* 至于该指针指向的对象,内容是否能变,那就管不着了,所以,对于如下语句:

* final StringBuffer strConst = new StringBuffer();

* 你可以修改它指向的对象的内容,比如:strConst.append("");

* 但是不能修改它的值,比如: strConst = null;

*/

/**

* reference:

*/

public class SystemCopy

{

/*

* 重点在Person person2 = person1;这一句上,person1里面包括了一个对Car对象的引用,

* 那么这句话是深拷贝还是浅拷贝呢?答案是什么都不是。它只是一个简单的引用传递,执行完这句话以后,

* person1和person2都指向了同一个person对象,所以无论谁去改变对象,另一个引用再去调用该对象

* 的值都会发生改变

*/

/* public static void main(String[] args)

{

Car car1 = new Car();

car1.setBrand("BMW");

car1.setPrice(10000);

Person person1 = new Person();

person1.setCar(car1);

person1.setName("person1");

Person person2 = person1;

person2.setName("person2");

System.out.println(person1.getName()); // person2

System.out.println(person2.getName()); // person2

Car car2 = new Car();

car2.setBrand("Benz");

car2.setPrice(20000);

person1.setCar(car2);

System.out.println(person2.getCar().getBrand()); // Benz

System.out.println(person2.getCar().getPrice()); // 20000

}*/

/**

* Car类不变,Person实现了Cloneable接口,然后重载了父类的clone方法,并且直接调用super.clone()

* 方法来拷贝。但是值得注意的是,父类的clone只是浅拷贝,所以才会有上述的输出结果。那么,要想达到深拷

* 贝,需要做些什么呢? 其实答案已经很明显了,因为clone是浅拷贝,而Car中都是原始类型的变量,所以我们

* 只需要让Car类也实现Cloneable接口,然后重载clone方法,然后回到Person类中,在clone的时候,加上

* car = car.clone()就行了

* @throws IOException

* @throws ClassNotFoundException

*/

/* public static void main(String[] args)

{

Car car1 = new Car();

car1.setBrand("BMW");

car1.setPrice(10000);

Person originalPerson = new Person();

originalPerson.setCar(car1);

originalPerson.setName("originalPerson");

Person clonePerson = (Person)originalPerson.clone();

originalPerson.setName("originalPerson_1");

originalPerson.getCar().setBrand("Benz");

System.out.println(originalPerson.getName());

System.out.println(originalPerson.getCar().getBrand());

System.out.println(clonePerson.getName());

System.out.println(clonePerson.getCar().getBrand());

}*/

/**

* 让Car 类实现Serializable 接口使其能够序列化, 其次就可以使用java的 Io来传输对象了,序列化能够达到深拷贝目的

* 的原因是,它首先将整个对象进行持久化,然后全部读出, 每读出一次就得到一个全新的拷贝, 序列化较cloneable 效率低,

* 究竟什么时候用浅拷贝, 什么时候用深拷贝, 答案是如果一个对象中只包含原始类型的变量,那么就使用浅拷贝, 如果类中有

* 对其它类的引用, 但是其它类是immutable的,仍然使用浅拷贝,如果有对其它类的引用, 而其它类是可被修改的, 就不得不

* 深拷贝了;

*/

public static void main(String[] args) throws IOException, ClassNotFoundException

{

Car originalCar = new Car();

originalCar.setBrand("BMW");

originalCar.setPrice(500000);

ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);

objectOutputStream.writeObject(originalCar);

objectOutputStream.flush();

ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());

ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);

Car cloneCar = (Car) objectInputStream.readObject();

System.out.println(cloneCar.getBrand()); // BMW

System.out.println(cloneCar.getPrice()); // 500000

cloneCar.setBrand("Honda");

cloneCar.setPrice(3000);

System.out.println(originalCar.getBrand()); // BMW

System.out.println(originalCar.getPrice()); // 500000

System.out.println(cloneCar.getBrand()); // Honda

System.out.println(cloneCar.getPrice()); // 3000

}

}

 类似资料: