Entity 실체 류 는 왜 Serializable 인 터 페 이 스 를 실현 해 야 직렬 화 됩 니까?
6196 단어 자바serializable서열 화
이 의문 을 일 으 키 는 것 은 Hibernate 에서 검색 캐 시 를 사용 하 는 것 부터 시작 합 니 다.대상 인 스 턴 스 는 메모리 외 에 도 2 급 캐 시 는 대상 을 하 드 디스크 에 기록 하여 필요 할 때 다시 읽 어 사용 합 니 다.이 때 는 하나의 개념 을 언급 해 야 합 니 다.직렬 화.
프로그램 이 실 행 될 때 인 스 턴 스 대상 을 만 듭 니 다.이 대상 들 은 메모리 에 존재 합 니 다.프로그램 이 실 행 될 때 사라 집 니 다.그러나 일부 대상(일반적으로 서로 다른 속성)을 저장 하거나 다른 프로 세 스에 전송 하려 면 프로그램 이 실 행 된 후에 도 이러한 이미지 가 존재 합 니 다.프로그램 이 다시 실 행 될 때 이 대상 들 의 정 보 를 읽 을 수 있 습 니 다.또는 다른 프로그램 에서 저 장 된 대상 정 보 를 이용 하여 인 스 턴 스 대상 으로 복원 합 니 다.이런 상황 에서 대상 의 서열 화 와 반 서열 화 를 사용 해 야 한다.
사실은 자바 에서 흔히 볼 수 있 는 몇 가지 유형,예 를 들 어 Interger/string 등 은 모두 자바.io.Serializable 인 터 페 이 스 를 실현 했다 는 것 을 일찍부터 알 고 있 었 다.이 직렬 화 인 터 페 이 스 는 아무런 방법 과 도 메 인 이 없고 표지 의 직렬 화 된 의미 에 만 사용 된다.Serializable 인 터 페 이 스 를 실현 하 는 클래스 는 직렬 화 될 수 있 으 며,이 인 터 페 이 스 를 실현 하지 않 은 클래스 는 직렬 화 되 거나 반 직렬 화 될 수 없습니다.직렬 화 류 의 모든 하위 클래스 자 체 는 직렬 화 될 수 있 으 며,Serializable 인 터 페 이 스 를 명시 적 으로 실현 할 필요 가 없습니다.직렬 화 를 거 쳐 야 대상 이 디스크 텍스트 와 네트워크 에서 의 전송,대상 을 복구 할 때 반 직렬 화 등 을 호 환 할 수 있 습 니 다.
문제 1:왜 서열 화 를 실현 해 야 합 니까?
답:직렬 화 는 인 스 턴 스 대상 의 상태(State 대상 속성 은 대상 방법 을 포함 하지 않 음)를 유 니 버 설 인 코딩(예 를 들 어 포맷 된 바이트 코드)하고 저장 하여 대상 의 완전 성과 전달 성 을 확보 하 는 것 입 니 다.
한 마디 로 하면 직렬 화 는 서로 다른 시간 이나 플랫폼 의 JVM 간 에 인 스 턴 스 대상 을 공유 하기 위 한 것 이다.
// :
public static void main(String[] args) throws Exception {
File file = new File("user.ser");
ObjectOutputStream oout = new ObjectOutputStream(new FileOutputStream(file));
User user = new User("zhang", 18, Gender.MALE);
oout.writeObject(user);
oout.close();
ObjectInputStream oin = new ObjectInputStream(new FileInputStream(file));
Object newUser = oin.readObject();
oin.close();
System.out.println(newUser);
}
Serializable 인터페이스 가 구현 되 지 않 으 면 직렬 화 할 때 Object Output Stream 의 write(object)방법 으로 대상 을 저장 할 때 이상 이 발생 합 니 다.실은 java.io.Serializable 은 속성 과 방법 이 없 는 빈 인터페이스 일 뿐 인 데 문제 가 생 겼 어 요...
문제 2:왜 꼭 실현 해 야 하 는가 Serializable 서열 화 를 할 수 있 을까요?
ObjectOutputStream 을 사용 하여 대상 을 지속 시 키 고, 이 곳 에서 던 진 이상 에 대해 서 는 다음 과 같이 확인 하 십시오.
private void writeObject0(Object obj, boolean unshared) throws IOException {
// ...
// remaining cases
if (obj instanceof String) {
writeString((String) obj, unshared);
} else if (cl.isArray()) {
writeArray(obj, desc, unshared);
} else if (obj instanceof Enum) {
writeEnum((Enum) obj, desc, unshared);
} else if (obj instanceof Serializable) {
writeOrdinaryObject(obj, desc, unshared);
} else {
if (extendedDebugInfo) {
throw new NotSerializableException(
cl.getName() + "
" + debugInfoStack.toString());
} else {
throw new NotSerializableException(cl.getName());
}
}
// ...
}
이로부터 알 수 있다.쓰기 대상 유형 이 String,배열,Enum,Serializable 이면 직렬 화 할 수 있 으 며,그렇지 않 으 면 NotSerializable Exception 을 던 집 니 다.
마지막 으로 주의:
1.직렬 화 대상 일 때 현재 대상 자 체 를 직렬 화 할 뿐만 아니 라 이 대상 이 인용 한 다른 대상 도 직렬 화 할 것 이다.이렇게 인용 전달 직렬 화.한 대상 에 포 함 된 구성원 변수 가 용기 류 등 이 고 심층 적 으로 인용 된다 면 직렬 화 과정 비용 도 비교적 크다.
2.필드 가 transient 로 밝 혀 지면 기본 직렬 화 체 제 는 이 필드 를 무시 합 니 다.(그리고 방법 은 writeObject 방법 을 사용자 정의 하 는 것 입 니 다.코드 예제 참조)
3.단일 클래스 에 readResolve()방법(단일 대상 으로 직접 돌아 가기)을 추가 하여 직렬 화 과정 에서 단일 특성 을 유지 하도록 합 니 다.
그리고 보충 해 주세요.
경로 아래 jdk 에는 또 다른 형식의 대상 이 지속 된다.즉,외부 화(Externalization)이다.
public interface Externalizable extends java.io.Serializable {
void writeExternal(ObjectOutput out) throws IOException;
void readExternal(ObjectInput in) throws IOException, ClassNotFoundException;
}
외부 화 와 직렬 화 는 같은 목 표를 실현 하 는 두 가지 다른 방법 이다.
Serializable 인 터 페 이 스 를 통 해 대상 의 서열 화 지원 은 jdk 에서 지원 합 니 다 API,그러나 자바.io.Externalizable 의 모든 실현 자 는 읽 기와 쓰기 의 구체 적 인 실현 을 제공 해 야 합 니 다.어떻게 실현 하 는 지 는 완전히 사용자 정의 입 니 다.직렬 화(Serializable) )필요 한 모든 정보(예 를 들 어 속성 및 속성 유형 등)를 자동 으로 저장 합 니 다.반 직렬 화 를 통 해 원래 와 같은 인 스 턴 스 로 만 들 고 외부 화(Externalizable)는 저 장 된 인 스 턴 스 에 필요 한 정보 만 저장 합 니 다.
예제 코드 는 다음 과 같다.
public class User implements Externalizable {
private String name;
transient private Integer age; //
private Gender gender;
public User() {
System.out.println("none constructor");
}
public User(String name, Integer age, Gender gender) {
System.out.println("arg constructor");
this.name = name;
this.age = age;
this.gender = gender;
}
//
private void writeObject(ObjectOutputStream out) throws IOException {
out.defaultWriteObject();
out.writeInt(age);
// gender
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
age = in.readInt();
}
//
@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject(name);
out.writeInt(age);
// gender
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
name = (String) in.readObject();
age = in.readInt();
}
}
Externalizable 로 직렬 화 합 니 다.대상 을 읽 을 때 직렬 화 된 클래스 의 무 참 구조 기 를 호출 하여 새로운 대상 을 만 든 다음 저 장 된 대상 의 필드 값 을 각각 새 대상 에 채 웁 니 다.Externalizable 인 터 페 이 스 를 실현 하 는 클래스 는 참여 하지 않 은 구조 기 를 제공 하고 접근 권한 은 Public 입 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.