Java 기본 - 데이터 직렬화를 위한 직렬화 프레임워크 사용

직렬화하는 이유는 무엇입니까?

요즘 개발 과정에서 상호 작용이 필요한 여러 프로세스와 여러 서비스 또는 서로 다른 언어로 된 서비스가 상호 작용해야 하는 경우가 종종 있습니다. 이때 일반적으로 고정 프로토콜을 사용하여 데이터를 전송하는 것을 선택하지만 많은 경우 Java 등의 언어에서는 전송되는 데이터가 고유한 클래스 객체이므로 클래스 객체는 현재 jvm에서만 유효하므로 다른 jvm이나 다른 언어로 전달하는 경우 클래스 객체를 직접 식별할 수 없습니다. 그렇다면 여러 서비스나 다른 언어로 상호 작용해야 하는 경우 어떻게 해야 합니까? 이때 고정된 프로토콜을 통해 고정된 데이터 형식을 전송해야 하는데, 이러한 데이터 전송 프로토콜을 직렬화(Serialization)라고 하며, 데이터를 전송하는 동작을 정의하는 프레임워크 구성요소를 직렬화 구성요소(프레임워크)라고도 합니다.
직렬화 프레임워크에는 두 가지 작업이 포함됩니다. 하나는 객체 또는 데이터 구조를 특정 형식(데이터 전송 프로토콜)으로 변환하는 것이며, 이를 직렬화라고 합니다. 다른 하나는 특정 형식을 객체 또는 데이터 구조로 변환하는 프로세스입니다. 역직렬화입니다.

직렬화의 목적

  • 데이터를 네트워크를 통해 전송하거나 메모리나 파일에 저장할 수 있습니다.
  • 데이터가 애플리케이션과 독립적으로 존재하도록 허용합니다.

직렬화 사용 시나리오

서로 다른 서비스 간의 상호 작용, 서비스는 동일한 언어일 수도 있고 다른 언어일 수도 있습니다.

Java 언어 내장 직렬화

직렬화의 구현은 텍스트 직렬화, 언어 내장 직렬화, 언어 간 직렬화로 나눌 수 있으며, 이 기사에서는 주로 Java 언어 내장 직렬화에 대해 설명합니다.
각 언어에는 기본적으로 직렬화 프레임워크가 구현되어 있습니다. 이 직렬화 방법을 언어 내장 직렬화라고 합니다. 장점은 언어가 직렬화 프레임워크(직렬화 프로토콜, 직렬화 및 역직렬화 작업)를 제공한다는 것입니다. 사용하기 쉽고 단점은 대화형 응용 프로그램이라는 것입니다. 동일한 언어로 작성되어야 합니다.
다음은 Java에 내장된 직렬화 프레임워크의 사용을 설명합니다.Java 직렬화 프로토콜은 바이트 시퀀스(jvm에 의해 구현됨)입니다.

직렬화 프레임워크에서 사용되는 코어
  • 직렬화 인터페이스(직렬화 가능 및 외부화 가능)

    직렬화해야 하는 클래스 객체는 이 인터페이스를 상속해야 하며, 현재 인터페이스 수정으로 정의된 클래스 객체만이 지정된 방식으로 객체를 전송할 수 있습니다.

  • 직렬화ID-직렬VersionUID

    버전 불일치로 인한 직렬화 실패를 방지하기 위해 전송/읽기에 사용되는 이중 종료 프로세스(javaBean)의 버전이 일치하는지 확인하십시오.
    컴파일러는 ID를 직렬화하는 두 가지 방법을 제공합니다. 하나는 값이 1L인 기본 versionID를 생성하는 것이고, 다른 하나는 클래스 이름, 인터페이스 이름, 멤버 메서드 및 속성을 기반으로 64비트 해시 필드를 생성하는 것입니다. 등, 클래스 이름, 메서드 이름, 변수가 수정되거나 공백, 주석, 개행 및 기타 작업이 있는 한 계산된 해시 필드는 달라집니다. 물론 여기에 주의해야 합니다. 다시 시도해 보세요 . -위 작업이 있을 때마다 실행하십시오.serialVerionUID를 한 번 생성하십시오(컴파일러는 이를 자동으로 수정하지 않습니다).
    기본 고정 값인 1L과 64비트 해시 값은 직접 계산할 필요가 없으며 직렬화 인터페이스를 상속하는 클래스의 경우 직렬화 ID 필드가 없으면 클래스 이름 아래에 노란색 물결선이 표시됩니다. 클래스 이름에 마우스를 놓고 원하는 방법을 선택하면 직렬화된 ID 필드가 자동으로 추가됩니다. (변경 사항이 있으면 삭제한 후 프롬프트에 따라 추가하세요.)

  • 객체 직렬화 및 데이터 쓰기 작업(출력 스트림 java.io.ObjectOutputStream)

    직렬화 작업을 수행하고 직렬화된 데이터를 파일에 쓰거나 전송하는 데 사용됩니다.

  • 데이터 읽기 및 객체 역직렬화 작업(입력 스트림 java.io.ObjectInputStream)

    네트워크에서 수신한 파일이나 데이터를 객체로 역직렬화하기 위해 역직렬화 작업을 수행하는 데 사용됩니다.

사례 1 - 기본 직렬화 및 역직렬화 직렬화 가능

다음은 파일에 저장된 직렬화된 객체를 사용하여 파일을 읽은 다음 객체를 예로 사용하여 직렬화 프레임워크의 사용을 설명합니다. 이 사용은 데이터를 전송하기 전에 직렬화하는 것과 동일합니다. 데이터 전송 및 파일 액세스 입력 및 출력 스트림, 입력 및 출력 스트림을 얻기 위한 매개 변수만 일치하지 않습니다.

개인 클래스 구현
public class Person implements Serializable {
    
    
	//64位哈希序列化ID
	private static final long serialVersionUID = 8247451571741032209L;
	private String name;
	private int age;
	private transient boolean isMan; // true=男,false=女

	public Person(String name, int age, boolean isMan) {
    
    
		this.name = name;
		this.age = age;
		this.isMan = isMan;
	}

	public String getName() {
    
    
		return name;
	}

	public void setName(String name) {
    
    
		this.name = name;
	}

	public int getAge() {
    
    
		return age;
	}

	public void setAge(int age) {
    
    
		this.age = age;
	}

	public boolean isMan() {
    
    
		return isMan;
	}

	public void setMan(boolean isMan) {
    
    
		this.isMan = isMan;
	}
	
	/*此方法只是用于打印,与序列化无关*/
    public String toString() {
    
    
        return "Person{" + "name=" + name  + ",age = " + age+",isMan = " + isMan + "}";
    }

}
직렬화 작업
public static void writeObject() {
    
    
		try {
    
    
			// 0. 创建一个ObjectOutputStream输出流
			ObjectOutputStream oos = new ObjectOutputStream(
					new FileOutputStream("E:/object.txt"));
			// 1. 将对象序列化到文件s
			Person person = new Person("lilu", 18, true);
			oos.writeObject(person);
			System.out.println("Person对象已写入object.txt文件");
		} catch (Exception e) {
    
    
			e.printStackTrace();
		}
	}
역직렬화 작업
public static void readObject() {
    
    
		try {
    
    
			// 0. 创建ObjectInputStream
			ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
					"E:/object.txt"));
			Person person1 = (Person) ois.readObject();
			System.out.println("读取到的Person对象数据如下:");
			System.out.println(person1);
		} catch (Exception e) {
    
    
			e.printStackTrace();
		}
	}
주요 함수 호출
public static void main(String[] args) {
    
    
		writeObject();
		readObject();
	}
작업 결과

여기에 이미지 설명을 삽입하세요.

Java 직렬화 사용법 요약
  • Java 직렬화는 객체 속성(객체 클래스 이름, 변수 유형, 변수 데이터) 전송에만 사용되며 메서드는 직렬화 프로세스와 아무 관련이 없습니다.
  • 클래스의 특정 멤버 변수는 직렬화할 필요가 없으며, 필드를 선언하기 위해 Transient를 사용합니다.
  • 클래스 정적 변수(정적으로 수정된 변수)는 직렬화되지 않습니다.
  • 멤버는 참조 직렬화이며 이 참조 유형에 해당하는 클래스도 직렬화 가능해야 합니다.
  • 직렬화는 전이적입니다. 상위 클래스가 직렬화를 구현하면 하위 클래스는 직렬화 인터페이스를 명시적으로 구현하지 않고 자동으로 직렬화를 구현합니다. 결과적으로 하위 클래스는 직렬화를 구현하고 상위 클래스는 직렬화를 구현하지 않습니다. 실패합니다. 동일한 객체가 여러 번 직렬화되면 동일한 객체가 여러 번 직렬화되지 않고, 직렬화 작업을 아무리 많이 수행해도 동일한 객체만 얻게 됩니다.

확장하다

  • 사용자 정의 직렬화, writeObject 및 readObject 재정의
  • 인터페이스 상속 외부화 가능
  • 직렬화 프레임워크의 소스 코드에 대한 자세한 설명
  • 언어 간 직렬화 구현

참고 링크

Java 직렬화, 이 기사를 읽어보세요!
JAVA 직렬화에 대한 자세한 설명
초보자 튜토리얼 - Java 직렬화

추천

출처blog.csdn.net/li1500742101/article/details/105509360