JavaRush /Java Blog /Random-KO /"Java의 직렬화 가능 클래스 내에서 SerialVersionUID를 사용하는 이유" 기사에 대한 응...
Сергей
레벨 31
Киев

"Java의 직렬화 가능 클래스 내에서 SerialVersionUID를 사용하는 이유" 기사에 대한 응답

Random-KO 그룹에 게시되었습니다
그래서.. 우리는 전통적인 방법을 사용하여 직렬화하려는 클래스가 있습니다(우리는 를 사용합니다 Serializable) ."Java의 직렬화 가능 클래스 내에서 SerialVersionUID를 사용하는 이유" 기사에 대한 응답 - 1
package Serialization;

import java.io.Serializable;

public class SerializableClass implements Serializable {
    private String name;
    private int number;
 }
테스트 신청서를 작성 중입니다. 내 목표는 무엇인지 보여주는 것이라고 바로 말씀 드리겠습니다 serialVersionUID.
package Serialization;

import java.io.*;

public class MainSerializable {
    final static String FILE_NAME = "c:\\File.dat";

    public static void serialize(Object object) throws IOException {
        FileOutputStream fileOutputStream = new FileOutputStream(FILE_NAME);
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);

        objectOutputStream.writeObject(object);

        fileOutputStream.close();
        objectOutputStream.close();
    }

    public static Object deserialize() throws IOException, ClassNotFoundException {
        FileInputStream fileInputStream = new FileInputStream(FILE_NAME);
        ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);

        Object object = objectInputStream.readObject();

        objectInputStream.close();

        return object;
    }

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        SerializableClass serializableClass = new SerializableClass();

        serialize(serializableClass);

        SerializableClass newObject = (SerializableClass) deserialize();
    }
}
모든 것이 잘 작동합니다. 클래스는 파일로 직렬화됩니다 FILE_NAME = "c:\\File.dat". 어두워지고 있었습니다... :) 수업에 필드를 추가하는 것을 잊었습니다. 추가하다:
public class SerializableClass implements Serializable {
    private String name;
    private int number;
    private String FirstName;   // +
    private String LastName;    // +
 }
모든 것이 괜찮은 것 같습니다. 모든 것이 컴파일됩니다. 그래서 실행하고 " " 파일에서 main클래스를 역직렬화합니다 . SerializableClassc:\\File.dat
public static void main(String[] args) throws IOException, ClassNotFoundException {
    SerializableClass newObject = (SerializableClass) deserialize();
}
아... 어떡하지...
Exception in thread "main" java.io.InvalidClassException: Serialization.SerializableClass; local class incompatible: stream classdesc serialVersionUID = 8129437039424566964, local class serialVersionUID = -8271479231760195917
	at java.base/java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:689)
	at java.base/java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1903)
	at java.base/java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1772)
	at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2060)
	at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1594)
	at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:430)
	at Serialization.MainSerializable.deserialize(MainSerializable.java:22)
	at Serialization.MainSerializable.main(MainSerializable.java:30)
일반적으로 모든 것이 공정합니다. 클래스가 변경되었으며 해당 serialVersionUID= -8271479231760195917가 파일 serialVersionUID= 에 직렬화되었습니다 8129437039424566964. 이제 무엇을 해야 할까요, 무엇을 해야 할까요? 인스턴스를 만드는 방법은 무엇입니까? 출구가 있습니다. 우리는 파일에서 회색으로 표시된 :) 클래스와 static final long serialVersionUID동일한 클래스 를 선언해야 합니다 . serialVersionUID저것들. 역직렬화하겠습니다.. 할 수 있습니다. 버전은 동일합니다.
package Serialization;

import java.io.Serializable;

public class SerializableClass implements Serializable {
    static final long serialVersionUID = 8129437039424566964L;

    private String name;
    private int number;
    private String FirstName;   // +
    private String LastName;    // +
}
우리는 시작합니다... 그리고... 모든 것이 작동합니다. 제가 이해한 대로, 클래스가 미리 선언했다면 이 오류를 피할 수 있었을 것입니다:
public class SerializableClass implements Serializable {
    static final long serialVersionUID = 1L;

    private String name;
    private int number;
}
저것들. serialVersionUID우리는 Java가 자체 알고리즘(매우 복잡한 알고리즘)을 기반으로 자체 계산을 수행하도록 허용하지 않습니다 . 이제 클래스가 변경될 때마다 다음을 serialVersionUID = 1L 확인합니다.
public static void main(String[] args) throws IOException, ClassNotFoundException {
    SerializableClass serializableClass = new SerializableClass();

    serialize(serializableClass);

    SerializableClass newObject = (SerializableClass) deserialize();
}
작동합니다. 이제 다음과 같습니다.
public class SerializableClass implements Serializable {
    static final long serialVersionUID = 1L;

    //private String name;
    //private int number;
}
응.. 그래서?
public class SerializableClass implements Serializable {
    static final long serialVersionUID = 1L;
    public int A;
    protected String value;
    //private String name;
    //private int number;
}
멋지네요.. 모든 것이 계속 작동합니다. 그래서 첫 번째 기사를 마쳤습니다. 댓글에 다 넣고 싶었는데 기호가 다 들어가지 않네요. 냉정한 비판과 의견을 받아들이겠습니다. PS 이러한 즐거움을 누릴 수 있도록 영감을 주신 저자에게 감사드립니다. 아마도 이것이 그들이 배우는 방법일 것입니다 :) 모두에게 행운을 빕니다 :)
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION