ProgramingTip

자바 커스텀 생성 화

bestdevel 2020. 12. 1. 19:14
반응형

자바 커스텀 생성 화


더 많은 수없는 필드가 포함 된 개체가 있습니다. 제안 수없는 별도의 API에서 제안하는 것입니다. 주요 문제는 위치 클래스입니다. 여기에는 내가 필요로하는 가지가 모두 포함되어 있습니다. read / writeObject를 사용하여 다음과 같은 작업을 수행 할 수있는 방법을 만들려면 어떻게해야합니까?

// writeObject:
List<Integer> loc = new ArrayList<Integer>();
loc.add(location.x);
loc.add(location.y);
loc.add(location.z);
loc.add(location.uid);
// ... serialization code

// readObject:
List<Integer> loc = deserialize(); // Replace with real deserialization
location = new Location(loc.get(0), loc.get(1), loc.get(2), loc.get(3));
// ... more code

어떻게 할 수 있습니까?


Java는 Custom Serialization을 지원합니다 . 기본 프로토콜 사용자 지정 섹션을 개발합니다.

인용 비용 :

그러나 이상하면서도 교활한 해결책이 있습니다. 두 가지 메소드를 제공하여 개발자는 기본 제공 기능을 사용하여 개발자는 클래스 파일을 생성합니다. 그 방법은 다음과 가능합니다.

  • private void writeObject (ObjectOutputStream out) throws IOException;
  • private void readObject (ObjectInputStream in) throws IOException, ClassNotFoundException;

이 메서드에서 수행 할 수있는 작업은 JSON 또는 기타 위치에 대한 ArrayList 또는 같은 경우에 필요한 경우 형식으로 다시 데이터하는 것입니다.

예를 들어 다음 코드를 추가합니다.



private void writeObject(ObjectOutputStream oos)
throws IOException {
    // default serialization 
    oos.defaultWriteObject();
    // write the object
    List loc = new ArrayList();
    loc.add(location.x);
    loc.add(location.y);
    loc.add(location.z);
    loc.add(location.uid);
    oos.writeObject(loc);
}

private void readObject(ObjectInputStream ois)
throws ClassNotFoundException, IOException {
    // default deserialization
    ois.defaultReadObject();
    List loc = (List)ois.readObject(); // Replace with real deserialization
    location = new Location(loc.get(0), loc.get(1), loc.get(2), loc.get(3));
    // ... more code

}


@momo의 대답과 대화하지만 목록 및 자동 상자 int 값을 사용하지 않고 훨씬 더 간결합니다.

private void writeObject(ObjectOutputStream oos) throws IOException {
    // default serialization 
    oos.defaultWriteObject();
    // write the object
    oos.writeInt(location.x);
    oos.writeInt(location.y);
    oos.writeInt(location.z);
    oos.writeInt(location.uid);
}

private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
    // default deserialization
    ois.defaultReadObject();
    location = new Location(ois.readInt(), ois.readInt(), ois.readInt(), ois.readInt());
    // ... more code

}

이 자바 직렬화를해야하는 경우, 내가 알고있는 유일한 방법은 다시 정의하는 것입니다 readObject()writeObject()의 인스턴스에 대한 참조 가진 모든 클래스에 Location모모의 대답과 같이합니다. 이렇게하면을 직렬화 할 수 없으며 코드에 나타나는 Location[]모든 항목을 하위 클래스로 분류 Collection<Location>해야합니다. 또한 유형의 필드가 Location과도 상태로 표시되어야하므로 해당 정의가 직렬화 스트림에 기록되지 않도록 제외하여 호환되지 않는 클래스 변경 감지를 방해 할 수 있습니다.

더 나은 방법은 단순히 ObjectOutputStream.writeObject. 아아, 그 방법은 final. 당신은 무시할 수있는 ObjectOutputStream.writeObjectOverride()대신,하지만 방법은 기본 구현을 위임 할 수 없습니다 ObjectOutputStream.writeObject0()그 방법이기 때문이다 private. 물론 리플렉션을 사용하여 private 메서드를 호출 할 수 있지만 ...

따라서 제약 조건을 확인하는 것이 좋습니다. Java 직렬화 여야합니까? 정말 클래스의 정의를 변경할 수 없습니까 Location?

class에 소스 코드가 있다면 클래스 경로 Location에 추가 implements Serializable하고 추가하는 것은 매우 간단합니다 . 예, 라이브러리를 업그레이드 할 때마다이 작업을 다시 수행해야하지만 다른 방법보다 나을 수도 있습니다.

참고 URL : https://stackoverflow.com/questions/7290777/java-custom-serialization

반응형