221027 Serializable, DTO
Serializable(직렬화)
=>인스턴스를 다른 곳에 전송할 수 있도록 해주는 것
=>전송한다는 의미는 파일 단위로 읽고 쓰는 것도 전송으로 간주하고 컴퓨터와 컴퓨터 또는 Component와 Component 사이를 왔다갔다 하는 것도 전송한다고 합니다.
이럴 때 사용하는 값의 집합을 나타내기 위한 인스턴스를 DTO(Data Transfer Object)라고 합니다.
=>Java에서는 인스턴스 단위로 데이터를 전송하고자 하면 Serializable 인터페이스를 implements하면 됩니다.
별도의 메서드 구현이 필요 없음. 유일하게 추상메서드를 오버라이딩 할 필요도 없다. 그냥 implements하면 끝.
=>응용프로그램을 만들 때 자신만의 저장 형식을 갖고자 하는 경우 사용하고 안드로이드에서 Activity(화면) 사이에 데이터 전송을 하고자 하면 사용합니다.
=>DataInputStream과 DataOutputStream을 이용해서 사용합니다.
=>데이터를 전송하고 전송받을 때 데이터는 항상 하나로 만들어두는 것이 좋음
블랙박스나 이메일도 이 과정을 거친다.
/*
데이터의 분류
=>하나의 데이터(scala data): Byte, Short, Character, Integer, Long, Float, Boolean, 자바는 String도.
=>여러 개의 데이터(vector data)
배열과 List(Collection) : 동일한 종류의 비교 가능한 데이터-인덱스를 이용해서 데이터를 구분
VO클래스나 Map : 여러 개의 데이터를 하나로 묶을 때 사용-이름을 이용해서 데이터를 구분--->특별한 경우가 아니면 이거 사용. 인덱스로 구분하는건 만든 사람만 안다.
*/
1)직렬화를 위한 DTO클래스 생성
=>정수로 된 번호, 문자열로 된 이름, Date로 만들어진 생일을 저장
2)Main클래스를 만들어서 직렬화한 1개의 클래스를 확인하고 읽어오기
3)Main클래스를 만들어서 직렬화한 여러 개의 클래스를 확인하고 읽어오기
try~resource
=>jdk 1.7에서부터 지원되는 문법
=>Stream은 만들면 반드시 close를 해주어야 합니다.
하지 않으면 메모리 누수가 발생합니다.
형식
try(여기서 만든 객체가 AutoCloseable 인터페이스를 implements하고 있다면 close하지 않아도 try~catch구문을 벗어나면 자동적으로 close를 호출함){
}catch(Exception e){
}
단, AutoCloseable를 implements하고있는지 확인할 것.
DTO 클래스
package java_DTO.practice;
import java.io.Serializable;
import java.util.Date;
//인스턴스 단위로 읽고 쓰기가 가능한 클래스-Serializable 인터페이스 때문
public class DTOTestEx implements Serializable{
private int num;
private String name;
private Date birthday;
public DTOTestEx() {
super();
}
public DTOTestEx(int num, String name, Date birthday) {
super();
this.num = num;
this.name = name;
this.birthday = birthday;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
@Override
public String toString() {
return "DTOTestEx [num=" + num + ", name=" + name + ", birthday=" + birthday + "]";
}
}
Main
package java_DTO.practice;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Date;
public class SerializableMain {
public static void main(String[] args) {
//인스턴스 단위에 파일에 기록할 수 있는 객체를 생성
try (ObjectOutputStream oos =new ObjectOutputStream(new FileOutputStream("multiobject.txt"))){//이렇게하면 close()호출할 필요 없음.
//기록할 인스턴스 생성
DTOTestEx dto1 = new DTOTestEx(1, "아담", new Date());
DTOTestEx dto2 = new DTOTestEx(2, "강진축구", new Date());
//기록할 인스턴스가 여러개이므로 하나의 List로 묶어줍니다
ArrayList<DTOTestEx> list = new ArrayList<>();
list.add(dto1);
list.add(dto2);
//기록
oos.writeObject(list);//write는 한번만에 해야 함. 데이터는 하나. 파워포인트를 열 때 여러 개의 파워포인트를 열기 위해 파워포인트앱을 여러번 클릭하진 않음.
} catch (Exception e) {
System.out.println(e.getLocalizedMessage());
}
try(//인스턴스 단위에 파일에 읽어낼 수 있는 객체를 생성
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("multiobject.txt"))) {
//기록을 할 때 List를 사용했으므로 읽어올 때 List로 읽어와야 합니다.
ArrayList list = (ArrayList)ois.readObject();//형변환
for(Object obj : list) {
System.out.println(obj);
}
} catch (Exception e) {
System.out.println(e.getLocalizedMessage());
}
}
}
DTOTestEx [num=1, name=아담, birthday=Thu Oct 27 18:34:36 KST 2022]
DTOTestEx [num=2, name=강진축구, birthday=Thu Oct 27 18:34:36 KST 2022]
multiobject.txt파일에 깨져있는 어떤 글로 기록되어 있다. ObjectOutputStream으로 기록하고, ObjectInputStream으로 읽는 것.