某个类要想实现拷贝的功能,就必须实现Cloneable接口,并覆盖Object的clone()方法,才能真正实现克隆。
浅拷贝,一种默认的实现,Teacher类中的clone方法的实现就是浅拷贝。
Student类的clone方法就是深拷贝。注意super.clone返回的对象实际上是被类的对象,可以放心强制转换,至于为什么,我也不知道,估计得读虚拟机规范,从Object源码看也不到什么,因为是protect native Object clone();
import
java.util.
*
;
public class TestClone {
public static void main(String[] args)
{
Teacher t = new Teacher("Name",22);
Teacher m = (Teacher)t.clone();
System.out.println(m);
Student stu = new Student();
Student deepcloneSTU = (Student)stu.clone();
stu.courses.put(new Integer(1),"Math");
deepcloneSTU.courses.put(new Integer(100),"Java");
disp(stu.courses);
disp(deepcloneSTU.courses);
}
static void disp(HashMap h)
{
Set keySet = h.keySet();
Iterator it = keySet.iterator();
while(it.hasNext())
{
System.out.println(h.get(it.next()));
}
}
}
class Teacher implements Cloneable {
String name;
int age;
Teacher(String name,int age)
{
this.name = name;
this.age = age;
}
public Object clone()
{
try{
return super.clone();
}catch(CloneNotSupportedException e)
{
throw new Error("This should never happen!");
}
}
public String toString()
{
return name + " " + age;
}
}
class Student implements Cloneable {
HashMap courses = new HashMap();
Student(){}
public Object clone()
{
try{
Student stu = (Student)super.clone();
stu.courses = (HashMap)courses.clone();
return stu;
}catch(CloneNotSupportedException e)
{
throw new Error("This should never happen!");
}
}
}
public class TestClone {
public static void main(String[] args)
{
Teacher t = new Teacher("Name",22);
Teacher m = (Teacher)t.clone();
System.out.println(m);
Student stu = new Student();
Student deepcloneSTU = (Student)stu.clone();
stu.courses.put(new Integer(1),"Math");
deepcloneSTU.courses.put(new Integer(100),"Java");
disp(stu.courses);
disp(deepcloneSTU.courses);
}
static void disp(HashMap h)
{
Set keySet = h.keySet();
Iterator it = keySet.iterator();
while(it.hasNext())
{
System.out.println(h.get(it.next()));
}
}
}
class Teacher implements Cloneable {
String name;
int age;
Teacher(String name,int age)
{
this.name = name;
this.age = age;
}
public Object clone()
{
try{
return super.clone();
}catch(CloneNotSupportedException e)
{
throw new Error("This should never happen!");
}
}
public String toString()
{
return name + " " + age;
}
}
class Student implements Cloneable {
HashMap courses = new HashMap();
Student(){}
public Object clone()
{
try{
Student stu = (Student)super.clone();
stu.courses = (HashMap)courses.clone();
return stu;
}catch(CloneNotSupportedException e)
{
throw new Error("This should never happen!");
}
}
}
如何通过对象串行化的方式来做进行拷贝工作呢?
import
java.util.
*
;
import java.io. * ;
public class TestClone {
public static void main(String[] args) throws Exception
{
BMW mycar = new BMW();
ByteArrayOutputStream memoryOutputStream = new ByteArrayOutputStream();
ObjectOutputStream serializer = new ObjectOutputStream(memoryOutputStream);
serializer.writeObject(mycar);
serializer.flush();
ByteArrayInputStream memoryInputStream = new ByteArrayInputStream(memoryOutputStream.toByteArray( ));
ObjectInputStream deserializer = new ObjectInputStream(memoryInputStream);
BMW mycopycar = (BMW)deserializer.readObject();
mycar.add(new String("NB"));
mycopycar.add(new String("NBNB"));
System.out.println(mycar.hashCode());
System.out.println(mycopycar.hashCode());
System.out.println(mycar.equals(mycopycar));
}
}
class BMW implements Serializable
{
private int wheels;
private String model;
private ArrayList forTest;
BMW()
{
wheels = 4;
model = "530i";
forTest = new ArrayList();
}
public void add(Object o)
{
forTest.add(o);
}
public String toString()
{
return "WHEEL:" + wheels + "MODEL:" + model + forTest.toString();
}
public int hashCode()
{
return wheels + model.hashCode() + forTest.hashCode();
}
public boolean equals(Object o)
{
if(o == this)
return true;
if(o == null)
return false;
if(!(o instanceof BMW))
return false;
BMW bmw = (BMW)o;
if(bmw.wheels == wheels&&bmw.model.equals(model)&&bmw.forTest.equals(forTest))
return true;
else return false;
}
}
import java.io. * ;
public class TestClone {
public static void main(String[] args) throws Exception
{
BMW mycar = new BMW();
ByteArrayOutputStream memoryOutputStream = new ByteArrayOutputStream();
ObjectOutputStream serializer = new ObjectOutputStream(memoryOutputStream);
serializer.writeObject(mycar);
serializer.flush();
ByteArrayInputStream memoryInputStream = new ByteArrayInputStream(memoryOutputStream.toByteArray( ));
ObjectInputStream deserializer = new ObjectInputStream(memoryInputStream);
BMW mycopycar = (BMW)deserializer.readObject();
mycar.add(new String("NB"));
mycopycar.add(new String("NBNB"));
System.out.println(mycar.hashCode());
System.out.println(mycopycar.hashCode());
System.out.println(mycar.equals(mycopycar));
}
}
class BMW implements Serializable
{
private int wheels;
private String model;
private ArrayList forTest;
BMW()
{
wheels = 4;
model = "530i";
forTest = new ArrayList();
}
public void add(Object o)
{
forTest.add(o);
}
public String toString()
{
return "WHEEL:" + wheels + "MODEL:" + model + forTest.toString();
}
public int hashCode()
{
return wheels + model.hashCode() + forTest.hashCode();
}
public boolean equals(Object o)
{
if(o == this)
return true;
if(o == null)
return false;
if(!(o instanceof BMW))
return false;
BMW bmw = (BMW)o;
if(bmw.wheels == wheels&&bmw.model.equals(model)&&bmw.forTest.equals(forTest))
return true;
else return false;
}
}
记住,如果覆盖了equals方法,应该也覆盖hashCode(),因为如果两个对象相等也就是equals()返回true,那么这两个对象应该有相同的hashCode。