얕은 클론과 깊은 클론 및 서열화
1. 얕은 복제와 깊은 복제 개념인 얕은 복제(얕은 복제): 복제된 대상의 모든 변수는 원래의 대상과 같은 값을 포함하고 다른 대상에 대한 모든 인용은 원래의 대상을 가리킨다.다시 말하면 얕은 복제는 고려된 대상만 복제하고 인용된 대상은 복제하지 않는다는 것이다.2. 얕은 복제와 깊은 복제 개념의 깊은 복제(깊은 복제): 복제된 대상의 모든 변수는 원래의 대상과 같은 값을 포함하고 다른 대상을 인용하는 변수를 제외한다.다른 대상을 인용하는 변수는 복사된 새로운 대상을 가리키며, 더 이상 원래 인용된 대상이 아니다.다시 말하면 복제할 대상이 인용한 대상을 깊이 복제한 것이다.3. 자바의 clone () 방법 [Object 클래스에 정의됨] clone 방법은 대상을 복사하여 호출자에게 되돌려줍니다.일반적으로clone() 방법 만족: ① 모든 대상 x에 x.clone()!=x 클론 대상은 원래 대상과 같은 대상이 아니다 ② 모든 대상에 x.clone ().getClass () = x.getClass () 복제 대상은 원래 대상의 유형과 같다. ③ 대상 x의 equals () 방법이 적절하게 정의되면 x.clone ().equals(x)가 성립되어야 한다.4, Java의 대상 복제 ① 대상의 복사본을 얻기 위해 Object 클래스의 clone () 방법을 사용할 수 있습니다.② 파생 클래스에서 기본 클래스의 clone () 방법을 덮어쓰고 public[Object 클래스의 clone () 방법은 보호됨]으로 성명한다.③ 파생 클래스의 clone () 방법에서 슈퍼를 호출합니다.clone().④ 파생 클래스에서 Cloneable 인터페이스를 구현합니다.5, ① 파생 클래스에서 Object의 clone () 방법을 덮어쓸 때 슈퍼를 사용해야 하는 이유.clone ()는?실행 중, Object의clone () 는 복사할 대상이 어떤 대상인지 식별한 다음, 이 대상에 공간을 분배하고, 대상의 복사를 진행하며, 원시 대상의 내용을 하나하나 새 대상의 저장 공간으로 복사합니다.②java에서 계승한다.lang.object 클래스의 clone () 방법은 얕은 복사
프로그램 코드:
1), 일반 클론(얕은 클론)
package com.clone;
public class CloneTest1
{
public static void main(String[] args)throws CloneNotSupportedException
{
Student student = new Student();
student.setAge(20);
student.setName("zhangsan");
Student student2 = (Student)student.clone();
System.out.println(student2.getAge());
System.out.println(student2.getName());
System.out.println("~~~~~~~~~~~~~~~~~~");
student2.setName("lisi");
System.out.println(student.getName());
System.out.println(student2.getName());
}
}
class Student implements Cloneable
{
private int age;
private String name;
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age = age;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
@Override
public Object clone() throws CloneNotSupportedException
{
Object object = super.clone();
return object;
}
}
2), 딥 클로닝
package com.clone;
public class CloneTest2
{
public static void main(String[] args) throws CloneNotSupportedException
{
Teacher teacher = new Teacher();
teacher.setAge(40);
teacher.setName("Teacher Zhang");
Student2 s1 = new Student2();
s1.setAge(20);
s1.setName("zhangsan");
s1.setTeacher(teacher);
Student2 s2 = (Student2) s1.clone();
System.out.println(s2.getAge());
System.out.println(s2.getName());
System.out.println("~~~~~~~~~~~~~~~~~~~~~~");
System.out.println(s2.getTeacher().getAge());
System.out.println(s2.getTeacher().getName());
System.out.println("~~~~~~~~~~~~~~~~~~~~~~");
s2.getTeacher().setAge(50);
s2.getTeacher().setName("Teacher Li");
System.out.println(s1.getTeacher().getAge());
System.out.println(s1.getTeacher().getName());
}
}
class Teacher implements Cloneable
{
private int age;
private String name;
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age = age;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
@Override
public Object clone() throws CloneNotSupportedException
{
return super.clone();
}
}
class Student2 implements Cloneable
{
private int age;
private String name;
private Teacher teacher;
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age = age;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public Teacher getTeacher()
{
return teacher;
}
public void setTeacher(Teacher teacher)
{
this.teacher = teacher;
}
@Override
public Object clone() throws CloneNotSupportedException
{
Student2 student2 = (Student2) super.clone();
student2.setTeacher((Teacher) student2.getTeacher().clone());
return student2;
}
}
6. 대상을 흐름에 쓰는 과정은 서열화(Serilization) 과정이고 대상을 흐름에서 읽는 과정은 반서열화(Deserialization) 과정이라고 한다.흐름 속에 쓰인 것은 대상의 복사본이고 원 대상은 JVM에 존재한다는 것을 지적해야 한다.7. 자바 언어에서 대상을 깊이 복제하면 대상이 먼저 Serializable 인터페이스를 실현한 다음에 대상(실제로는 대상의 복사일 뿐)을 하나의 흐름에 쓴 다음에 흐름에서 읽으면 대상을 재구성할 수 있다.이렇게 하는 전제는 대상과 대상 내부에서 인용된 모든 대상이 직렬화될 수 있다는 것이다. 그렇지 않으면 직렬화할 수 없는 대상이transient로 설정될 수 있는지 자세히 고찰하여 복제 과정에서 배제해야 한다.8. 주의: Cloneable와 Serializable는 모두marker Interface이다. 즉, 그들은 단지 표지 인터페이스일 뿐이고 어떤 방법도 정의하지 않았다.9. 하나의 클래스가 Serializable 인터페이스를 실현했을 때 이 클래스가 서열화될 수 있음을 나타낸다. 이때 Eclipse는 이 클래스에 대한 필드를 정의할 것을 요구한다. 이 필드의 이름은 SerialVersionUID이고 유형은 long이다. 알림 정보는 다음과 같다. 10, Theserializable class Student4 does not declare a static final serialVersion UIDfield of type long11, Eclipse에서 하나를 생성할 수 있다.두 가지 생성 방식이 있는데 하나는 기본 1L이다. 예를 들어private static final long serialVersionUID = 1L이다.하나는 클래스 이름, 인터페이스 이름, 구성원 방법과 속성 등에 따라 64개의 해시 필드를 생성하는 것이다. 예를 들어private static final long serialVersion UID = 8940196742313994740L;뭐 그런 거.12. 하나의 클래스가 Serializable 인터페이스를 실현하면 SerialVersionUID를 정의하지 않으면 Eclipse는 이 알림 기능을 제공하여 정의를 알려 줍니다.Eclipse에서 클래스에서 Warning의 아이콘[즉 그 노란색 아이콘]을 클릭하면 Eclipse는 자동으로 두 가지 생성 방식을 정한다. 위에서 말한 바와 같다.정의하지 않으려면 Eclipse 설정에서도 끄실 수 있습니다. 설정은 다음과 같습니다. Window=>Preferences=>Java=>Compiler=>Error/Warnings==>Potential programming problems는 Serializable class without serialVersion UID의 Warning을 ignore로 변경하면 됩니다.13. 호환성 문제를 고려하지 않았을 때 끄세요. 그러나 이 기능은 좋습니다. 어떤 종류가 Serializable라는 인터페이스를 실현하면 SerialVersionUID를 추가하지 않으면 Eclipse는 Warning 힌트를 줍니다. 이 SerialVersionUID는 이 종류의 Serializable가 앞으로 호환되도록 합니다.14. 만약에 당신의 대상이 서열화된 후에 하드디스크에 저장된 후에 클래스의field(증가 또는 감소 또는 개명)를 바꾸면 반서열화될 때 Exception이 나타나 호환성이 떨어지는 문제를 초래할 수 있다.그러나 SerialVersionUID와 동시에 다른 필드를 type의 기본값인 Deserialize로 설정하면 호환성 문제를 피할 수 있습니다.
3) 클론 프로그램 시리얼화
package com.clone;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class CloneTest3
{
public static void main(String[] args) throws Exception
{
Teacher3 t = new Teacher3();
t.setAge(40);
t.setName("Teacher Zhang");
Student3 s1 = new Student3();
s1.setAge(20);
s1.setName("zhangsan");
s1.setTeacher(t);
Student3 s2 = (Student3) s1.deepCopy();
System.out.println(s2.getAge());
System.out.println(s2.getName());
System.out.println("~~~~~~~~~~~~~~~~~~~");
System.out.println(s2.getTeacher().getAge());
System.out.println(s2.getTeacher().getName());
s2.getTeacher().setAge(50);
s2.getTeacher().setName("Teacher Li");
System.out.println("~~~~~~~~~~~~~~~~~~~");
System.out.println(s1.getTeacher().getAge());
System.out.println(s1.getTeacher().getName());
}
}
class Teacher3 implements Serializable
{
private int age;
private String name;
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age = age;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
}
class Student3 implements Serializable
{
private int age;
private String name;
private Teacher3 teacher;
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age = age;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public Teacher3 getTeacher()
{
return teacher;
}
public void setTeacher(Teacher3 teacher)
{
this.teacher = teacher;
}
public Object deepCopy() 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();
}
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
m1 이클립스에 oracle cloud (오라클 클라우드)연결하기m1에는 oracle이 설치되지 않는다.... 큰맘먹고 지른 m1인데 oracle이 설치되지 않는다니... 하지만 이뻐서 용서가 된다. 이거 때문에 웹 개발 국비수업을 듣는 도중에 몇번 좌절하고 스트레스를 크게 받았...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.