[CS] 직렬화(Serialization)

박현우·2021년 11월 9일
1

CS

목록 보기
16/20
post-custom-banner

직렬화(Serialization)란 무엇인가?

  • 객체를 직렬화하여 전송 가능한 형태로 만드는 것을 의미합니다.
  • 객체를 네트워크로 전송하기 위해 연속적인 데이터로 변환한뒤, Stream을 통해 데이터를 읽도록 합니다.
  • 주로 객체들을 통째로 파일로 저장하거나 전송하고 싶을 때 사용됩니다.
    역직렬화? 직렬화된 파일 등을 역으로 직렬화하여 다시 객체의 형태로 만드는 것.

직렬화가 되기 위한 조건

첫째, Serializable 인터페이스를 구현할 것.
둘째, 클래스 내 모든 멤버 변수가 Serializable을 구현해야 함.
셋째, transient를 이용하여 직렬화 대상에서 제외시킬수 있음.

예시를 보면 다음과 같습니다.

class Person implements Serializable {
		private int age;
		private String name;
		private transient String phoneNum; // 민감 정보 직렬화에서 제외

		Animal animal;   // Serializable 구현 X
		Vehicle vehicle; // Serializable 구현
		
		public Person(int age, String name, String phoneNum) {
			this.age = age;
			this.name = name;
			this.phoneNum = phoneNum;
		}

		@Override
		public String toString() {
			StringBuilder builder = new StringBuilder();
			builder.append("Person [age=").append(age).append(", name=").append(name).append("]");
			return builder.toString();
			
			
		}

	}

다음의 클래스는 직렬화가 불가능합니다. 왜냐하면 Serializable 인터페이스를 구현 하지 않은 Animal이 멤버 변수로 선언되어 있기 때문입니다.
또한, 직렬화된 객체


serialVersionUID이란?

  • serialVersionUID는 객체의 해시코드로 직렬화될 때 객체에 표시되는 식별자 역할을 합니다. serialver와 같은 툴로 객체의 serialVersionUID를 알아낼 수 있습니다.

  • 별도의 serialVersionUID를 클래스 내에 지정하지 않는다면, 컴파일러가 계산한 값을 부여합니다. 그러므로 컴파일러에 따라 부여하는 값이 다를 수 있습니다.

  • 컴파일러는 Serializble Class 혹은 Outer Class를 참고하여 만들기 때문에 클래스의 변경이 있으면 serialVersionUID도 바뀝니다.

  • 만약 serialVersionUID가 다르다면, InvalidClassException을 발생시킵니다.


객체를 쓰고 읽는 방법

객체를 직렬화 하여 파일 혹은 네트워크 상에 보내기 위해 Stream을 열어야 합니다. Stream을 열고 객체를 직렬화 해서 담는 것입니다.
ex)

FileOutputStream fos=new FileOutputStream("user.acc");
ObjectOutputStream oos=new ObjectOutputStream(fos);

이렇게 저장된 직렬화된 객체를 메모장으로 확인해보면, 멤버변수만 확인이 가능하고 메소드나 transient로 선언된 변수들은 확인할 수 없습니다.


다음은 객체를 읽는 방법입니다. 직렬화된 객체를 다시 역직렬화 하여 객체화 시켜야 합니다. 직렬화와 똑같이 Stream이 필요하며, 다음의 과정을 거칩니다.

  1. Stream을 연다. ex)FileInputStream
  2. ObjectInputStream을 통해 해당 Stream으로부터 직렬화된 객체(위 메모장)를 받아들인다.
  3. readObject를 통해 역직렬화하여 Object로 리턴받는다.
Account ruser=null;
		
FileInputStream fis=new FileInputStream("user.acc");
ObjectInputStream ois=new ObjectInputStream(fis);
ruser=(Account)ois.readObject();

ois.close();

ref.

post-custom-banner

0개의 댓글