深拷貝 淺拷貝 賦值
賦值:
class Teacher {
String name = "王老師";
}
class Student{
String name = “小A”;
Teacher teacher = new Teacher();
}
Student s1 = new Student();
Student s2 = s1;
s1 == s2,指向的內存區域相同
拷貝:
class Teacher {
String name = "王老師";
}
class Student implement Cloneable{
String name = “小A”;
Teacher teacher = new Teacher();
public Object clone() throws CloneNotSuppotredException{
return super.clone();
}
}
Student s1 = new Student();
Student s2 = s1.clone();
s1 != s2, 指向不同的內存區域
根據 s1.teacher 語 s2.teacher的內存區相不相同分爲深拷貝和淺拷貝
s1.teacher == s2.teacher 淺拷貝
s1.teacher != s2.teacher 深拷貝
想深拷貝避免不了要使用對象的序列化和反序列化技術,所以:
- 所有對象至少要實現Serializiable
- 需要拷貝的對象還要實現Cloneable,如下:
public Object clone() throws CloneNotSupportedException {
ByteArrayOutputStream baos = null;
ObjectOutputStream oos = null;
ObjectInputStream ois = null;
try {
baos = new ByteArrayOutputStream();
oos = new ObjectOutputStream();
oos.writeObject(this);
ois = ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
return ois.readObject();
}finally{
safeClose(baos);
safeClose(oos);
safeClose(ois);
}
retturn null;
}
public static void safeClose(Closeable closeable){
try{
if(closeable != null){
closeable.close();
}
}catch(IOException e){
e.printStackTrace();
}
}
補充:
- 可能有的需要將上述clone函數單獨提取出來,將object傳入,那麼就要注意ObjectInputStream需要防止外部不可信的數據入侵,可以新建SafeObjectInputStream類如下:
public class SafeObjectInputStream extends ObjectInputStream {
public SafeObjectInputStream(InputStream inputStream) throws IOException {
super(inputStream);
}
protected SafeObjectInputStream() throws IOException, SecurityException {
}
@Override
protected Class<?> resolveClass(ObjectStreamClass objectStreamClass) throws IOException, ClassNotFoundException {
if(objectStreamClass.getName().equals("com.example.whitename")){
return super.resolveClass(objectStreamClass);
}
throw new ClassNotFoundException(objectStreamClass.getName() + " not find");
}
}