자바 진급 시리즈 대상 클론
protected native Object clone() throws CloneNotSupportedException;
자세히 보면 네 이 티 브 방법 입 니 다. 네 이 티 브 방법 은 자바 언어 가 아 닌 코드 로 자바 프로그램 이 호출 할 수 있다 는 것 을 잘 알 고 있 습 니 다. 자바 프로그램 은 JVM 가상 컴퓨터 에서 실행 되 기 때문에 비교적 밑바닥 에 있 는 운영 체제 와 관련 된 것 을 방문 하려 면 어 쩔 수 없 이 운영 체제 에 가 까 운 언어 로 만 이 루어 질 수 있 습 니 다.
왜 복 제 를 합 니까?
여러분 은 먼저 한 가지 문 제 를 생각 하 세 요. 왜 복제 대상 이 필요 합 니까?그냥 뉴 대상 하면 안 돼 요?정 답 은 복 제 된 대상 은 수 정 된 속성 을 포함 할 수 있 으 며, new 에서 나 온 대상 의 속성 은 모두 초기 화 된 값 이기 때문에 현재 대상 의 '상태' 를 새로운 대상 으로 저장 하려 면 clone 방법 에 의존 합 니 다.그럼 제 가 이 대상 의 임시 속성 을 하나씩 할당 해 주 셔 도 되 지 않 겠 습 니까?그 럴 수 있 습 니 다. 하지만 첫째, 귀 찮 은 것 은 말 하지 않 겠 습 니 다. 둘째, 여러분 은 위의 소스 코드 를 통 해 clone 이 native 방법 이라는 것 을 알 게 되 었 습 니 다. 바로 빠 르 군요. 밑 에서 이 루어 진 것 입 니 다.우리 가 흔히 볼 수 있 는 Object a = new Object () 를 깨 웁 니 다.Object b;b=a;이러한 형식의 코드 는 인용, 즉 대상 이 메모리 에 있 는 주소, a 와 b 대상 이 여전히 같은 대상 을 가리 키 고 있 습 니 다.clone 방법 을 통 해 값 을 부여 하 는 대상 은 원래 의 대상 과 동시에 독립 적 으로 존재 합 니 다.이렇게 쓸데없는 말 을 많이 하 더 니 드디어 본론 으로 들 어 갔다.
어떻게 복 제 를 실현 합 니까?
믿 기지 않 을 정도 로 간단 해.클래스 뒤에 implements Cloneable 을 직접 설명 합 니 다.이 인터페이스 에 대한 원본 코드 는 다음 과 같 습 니 다.
public interface Cloneable {
}
그것 은 빈 인터페이스 로 표시 하 는 역할 을 하 는 것 을 볼 수 있다.Cloneable 인터페이스 가 구현 되 지 않 으 면 clone 방법 을 직접 사용 합 니 다. 프로그램 은 Clone NotSupported Exception 이상 을 던 집 니 다.그리고 클 라 이언 트 방법 을 다시 쓰 고 Public 접근 단계 로 수정 합 니 다.전형 적 인 밤 을 들 어 라.
class Outer implements Cloneable {
public int name;
public Inner inner;
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
public static void main(String[] args){
Outer o_one = new Outer();
o_one.inner = new Inner("zhangsan");
try {
Object obj = o_one.clone();
Outer o_two = (Outer)obj;
System.out.println(o_one==o_two); // false
System.out.println(o_one.inner.name.equals(o_two.inner.name)); // true
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
위의 코드 가 실 현 된 것 은 사실 얕 은 복제 이다. 얕 은 복 제 는 인용 유형 에 대해 서 만 복사 하고 인용 하 며 두 대상 을 진정 으로 독립 시 키 지 않 고 서로 관계 가 없다.얕 은 클론 이기 때문에 imp 2 는 child 의 특정한 속성 을 수정 한 후에 imp 1 에서 child 의 속성 도 달라 집 니 다.또는 두 대상 의 주 소 를 비교 합 니 다: imp1. child = imp2. child, 돌아 온 결 과 는 true 입 니 다.단, 대상 이 원본 데이터 필드 나 가 변 대상 필드 (예 를 들 어 String 형식) 만 포함 하고 있다 면 얕 은 복 제 를 추천 합 니 다.
심 클론
클래스 의 모든 인용 형식 을 수정 하여 Cloneable 인터페이스 도 실현 하도록 합 니 다.그리고 이 클래스 의 clone 방법 을 수정 합 니 다.
public class Inner implements Cloneable{
public String name;
public Child(String name) {
this.name = name;
}
@Override
public String toString() {
return "Inner name :" + name;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
이 종류의 clone 방법 을 수정 합 니 다:
static class Outer implements Cloneable {
public int count;
public Inner inner;
@Override
public Object clone() throws CloneNotSupportedException {
Outer obj = (Outer)super.clone();
obj.inner = (Inner) inner.clone();
return obj;
}
}
요점 을 그 렸 다.
인용 유형 에 인용 유형 이 많이 포함 되 어 있 거나 내부 인용 유형의 클래스 에 인용 유형 이 포함 되 어 있 으 면 clone 방법 을 사용 하 는 것 이 번 거 로 울 수 있 습 니 다.이때 우 리 는 대상 의 심 복 제 를 직렬 화 하 는 방식 으로 실현 할 수 있다.
public class Outer implements Serializable{
private static final long serialVersionUID = 369285298572941L; // ID
public Inner inner;
public Outer myclone() {
Outer outer = null;
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(this);
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
outer = (Outer) ois.readObject();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return outer;
}
}
Inner 도 Serializable 을 실현 해 야 합 니 다. 그렇지 않 으 면 직렬 화 할 수 없습니다.
public class Inner implements Serializable{
private static final long serialVersionUID = 872390113109L; // ID
public String name = "";
public Inner(String name) {
this.name = name;
}
@Override
public String toString() {
return "Inner name :" + name;
}
}
이렇게 하면 두 대상 이 메모리 공간 에서 완전히 독립 적 으로 존재 하고 상대방 의 값 에 영향 을 주지 않 게 할 수 있다.
Tips
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.