문제

나는 불변의 용도를 위해 의도 된 수업이 있으므로 모든 필드에 라벨을 붙이고 싶습니다. final.

그러나 클래스는 직렬화되고 네트워크를 통해 보낼 수 있습니다. 이것을 작동하려면 빈 생성자가 필요합니다. 이것은 내가 최종 필드를 만들지 못하게한다.

나는 이것이 상당히 일반적인 문제라고 확신하지만 해결책을 찾을 수 없습니다. 어떻게 진행해야합니까?

도움이 되었습니까?

해결책

일반적인 직렬화 사례에서 클래스에 빈 생성자 또는 비 결합 필드가 직렬화 할 수 있어야 할 필요는 없습니다.

이제 직렬화를 수행해야하거나 직렬화 할 수없는 클래스를 서브 클래스 해야하는 경우 다른 스토리입니다.

따라서 문제가있는 방법에 대한 자세한 내용을 제공해야합니다.

다른 팁

무기 생성자가 필요하지 않습니다. 가장 파생되지 않은 비-소화 가능한 클래스는 가장 많이 파생 된 일련 방지 가능한 클래스에서 사용할 수있는 아르그 생성자가 필요합니다.

a 내부의 필드를 돌연변이 해야하는 경우 readObject, 그런 다음 연속 프록시를 사용하십시오 readResolve 그리고 writeReplace.

이 문제는 다음과 같습니다 Java 언어에 버그를 열어줍니다. (이것은 readObject와 같이 직렬화를 수동으로 수행 해야하는 경우에만 적용됩니다).

말한 내용을 반영하기 위해, 당신이 당신이 java.io.Serializable 상호 작용. 살펴보십시오 java.lang.Integer 소스 코드 예를 들어, 두 개의 생성자가있는 간단한 직렬화 가능/불변성 클래스 : 하나는 int를 취하고 하나는 문자열을 취하는 클래스입니다. 소스 코드: http://www.docjar.com/html/api/java/lang/integer.java.html. Javadoc : http://java.sun.com/javase/6/docs/api/java/lang/integer.html.

또한 수업의 복잡성과하고있는 일에 따라 java.io.Externalizable 인터페이스 (일부는 구식으로 간주되지만 ARG 생성자가 필요합니다). 다음은 SO에 대한 개요입니다. Java에서 직렬화 가능한 것과 외부화 가능한 차이점은 무엇입니까?, 그리고 다음은 공식 Java 자습서입니다. http://java.sun.com/docs/books/tutorial/javabeans/persistence/index.html.

비슷한 문제가 있었기 때문에 기록을 위해.
나는 메시지가 있었다 "java.io.invalidclassexception : com.example.stuff.foobar; com.example.stuff.foobar; 유효한 생성자가 없습니다"

기본 생성자가 부족했기 때문이라고 생각했습니다. 그러나 위의 답변은 그것이 필수가 아니라는 것을 확인합니다 (그러나 우리의 앱은 실제로 기본 생성자가 필요한 기존 시리얼 라이저를 사용하므로 사례가 발생할 수 있습니다).

그런 다음 페이지를 찾았습니다.

상속을 위해 설계된 클래스를 직렬화 할 수없는 경우 직렬화 가능한 서브 클래스를 작성하는 것이 불가능할 수 있습니다. 구체적으로, 슈퍼 클래스가 접근 가능한 매개 변수없는 생성자를 제공하지 않으면 불가능합니다.

그러므로 내가받은 메시지는 생각합니다. 핵심 문제는 고전적인 것으로 보였습니다. 나는 수업을 직렬화 가능한 것으로 선언했지만 슈퍼 클래스는 그렇지 않았습니다! 나는 계층 구조에서 직렬화 가능한 인터페이스를 위로 옮겼다.

그러나 메시지는 약간 오해의 소지가있었습니다 ... :-)

무기 생성자가 필요하지 않습니다. 소스 코드를 읽자 :

// java.io.ObjectStreamClass
private static Constructor<?> getSerializableConstructor(Class<?> cl) {
    Class<?> initCl = cl;
    while (Serializable.class.isAssignableFrom(initCl)) {
        if ((initCl = initCl.getSuperclass()) == null) {
            return null;
        }
    }
    ...
}

따라서 실제로는없는 생성자가 가장 가까운 곳에서 필요합니다. Serializable 유형 계층 구조의 클래스.

그것은 다음 수업을 의미합니다 Domain 직렬화 될 수 있습니다.

class Domain implements Serializable {
    private final int a;

    public Domain(int a) {
      this.a = a;
    }
}

그러나 수업 Son 캔트:

class Father{
  private final int a;

  public Father(int a) {
    this.a = a;
  }
}

class Son extends Father implements Serializable {
  public Son(int a) {
    super(a);
  }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top