ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 자바 직렬화 & 역직렬화(2)_사용법
    Java 2023. 10. 9. 13:40

    직렬화 사용

    • 여러개의 객체를 역직렬화 할 때, 직렬화할때 순서와 일치해야 한다.
    • 부모-자식 상속 관계에서 부모 클래스가 Serializable을 구현했다면 자식 클래스는 Serializable을 구현하지 않아도 직렬화가 가능하다.
    • 부모 클래스는 Serializable을 구현하지 않고 자식 클래스만 구현했다면 직렬화할때 부모 클래스의 인스턴스 필드는 무시되고 자식 필드만 직렬화가 된다.
      • 상위 클래스의 필드까지 직렬화하려면 부모 클래스가 Serializable을 구현하도록 설정
    • 객체를 직렬화하기 위해선 java.io.Serializable 인터페이스를 implements 해야 된다. 그렇지 않으면 NotSerializableException 런타임 예외가 발생된다.
    import java.io.Serializable;
    
    class Board implements Serializable {
        int seq;
        String title;
        transient String contents; // 명시해주면 알아서 직렬화 대상에서 제외 (역직렬화 하면 null로 나온다.)
    
        public Board(int seq, String title) {
            this.seq = seq;
            this.title = title;
        }
    
        @Override
        public String toString() {
            return "Board{" +
                    "seq=" + seq +
                    ", title='" + title + 
                    '}';
        }
    }
    • 직렬화(스트림에 객체를 출력) 에는 ObjectOutputStream을 사용한다.
      • 객체가 직렬화될때 오직 객체의 인스턴스 필드값 만을 저장한다. static 필드나 메서드는 직렬화하여 저장하지 않는다.
    public static void main(String[] args) {
        // 직렬화할 고객 객체
        Board board = new Board(1, "boardTitle");
    
        // 외부 파일명
        String fileName = "Board.ser";
    
        // 파일 스트림 객체 생성 (try with resource)
        try (
                FileOutputStream fos = new FileOutputStream(fileName);
                ObjectOutputStream out = new ObjectOutputStream(fos)
        ) {
            // 직렬화 가능 객체를 바이트 스트림으로 변환하고 파일에 저장
            out.writeObject(board);
    
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    /*
        코드를 실행하면 Board.ser이라는 파일이 생성되고
        파일 내용에는 사람이 읽을 수 없는 문자 형태로 되어있다.
    */
    • 역직렬화(스트림으로부터 객체를 입력)에는 ObjectInputStream을 사용한다.
      • 직렬화 대상이 외부 클래스라면, 클래스 경로에 존재해야 하며 import된 상태여야 한다.
    public static void main(String[] args) {
        // 외부 파일명
        String fileName = "Board.ser";
    
        // 파일 스트림 객체 생성 (try with resource)
        try(
                FileInputStream fis = new FileInputStream(fileName);
                ObjectInputStream in = new ObjectInputStream(fis)
        ) {
            // 바이트 스트림을 다시 자바 객체로 변환 (이때 캐스팅이 필요)
            Board deserializedBoard = (Board) in.readObject();
            System.out.println(deserializedBoard);	// Board{seq=1, title='boardTitle'}
    
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    
    /*
        직렬화된 외부 파일만 있으면 생성자로 객체 초기화 없이 
        바로 객체에 정보를 가져와 인스턴스화 하여 사용할 수 있게 되는 마법 같은 기능을 얻을 수 있게 된다.
    */
    • 직렬화할 객체가 많다면 ArrayList와 같은 컬렉션에 저장해서 관리 하는것이 좋다. ArrayList 하나만 역직렬화하면 되므로 객체의 순서를 고려할 필요가 없어지기 때문이다.
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        // 직렬화할 고객 객체
        Board board1 = new Board(1, "title1");
        Board board2 = new Board(2, "title2");
        Board board3 = new Board(3, "title3");
    
        // 외부 파일명
        String fileName = "Board.ser";
    
        // 리스트 생성
        List<Board> boardList = new ArrayList<>();
        boardList.add(board1);
        boardList.add(board2);
        boardList.add(board3);
    
        // 리스트 자체를 직렬화 하기
        FileOutputStream fos = new FileOutputStream(fileName);
        ObjectOutputStream out = new ObjectOutputStream(fos);
        out.writeObject(boardList);
        
        out.close();
    
        // 역직렬화 하여 리스트 객체에 넣기
        FileInputStream fis = new FileInputStream(fileName);
        ObjectInputStream in = new ObjectInputStream(fis);
        List<Board> deserializedBoardList = (List<Board>) in.readObject();
        
        in.close();
        
        System.out.println(deserializedBoardList); // [Board{seq=1, title='title1'}, Board{seq=1, title='title2'}, Board{seq=1, title='title3'}]
    }

     

     

    출처)

    https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EC%A7%81%EB%A0%AC%ED%99%94Serializable-%EC%99%84%EB%B2%BD-%EB%A7%88%EC%8A%A4%ED%84%B0%ED%95%98%EA%B8%B0

Designed by Tistory.