- ์ฐ๋ฆฌ๋ InputObjectStream / OutputObjectStream ๋ฅผ ํตํด ๊ฐ์ฒด๋ฅผ ์ฝ๊ณ ์ด๋ค.
- ์ด ํด๋์ค์ ํฌํจ๋ ๋ฉ์๋๊ฐ readObject() / writeObject() ์ด๋ค.
- ํด๋์ค์ readObject() / writeObject() ๊ฐ ์ ์๋์ด ์๋ค๋ฉด, ๊ธฐ๋ณธ ์ง๋ ฌํ ๊ณผ์ ์์ ์ด ๋ฉ์๋๋ฅผ ํตํด ์ง๋ ฌํ์ ์ญ์ง๋ ฌํ๋ฅผ ์ํํ๋ค.
- ์ปค์คํ ํ ์ง๋ ฌํ (์ง๋ ฌํ์ ํน์ ์ฒ๋ฆฌ๋ฅผ ํ๊ณ ์ถ์ ๋) ์ฌ์ฉ.
- private ๋ฉ์๋๋ก ์์ฑํด์ผ ํ๋ค.
- ์ด ๋ฉ์๋๋ค์ ์ฒ์์ defaultWriteObject() / defaultReadObject() ๋ฅผ ํธ์ถํ์ฌ ๊ธฐ๋ณธ ์ง๋ ฌํ๋ฅผ ์คํํ๊ฒ ํด์ผํ๋ค.
- ๋ฆฌํ๋ ์ ์ ํตํด ์์ ์ ์ํํ๋ค.
- ์๋ก์ด ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด๋ด๋ ํน์ดํ public ์์ฑ์์ ๊ฐ๋ค๊ณ ํ ์ ์๋ค.
- ๋ฐ๋ผ์, ์์ฑ์์ฒ๋ผ
์ ํจ์ฑ๊ฒ์ฌ
,๋ฐฉ์ด์ ๋ณต์ฌ
๋ฅผ ์ํํด์ผํ๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด, ๋ถ๋ณ์์ ๋ณด์ฅํ์ง ๋ชปํ๋ค.
- readObject() ๋ฅผ ์ ์ํ์ง ์์์, ์๋ฐ์ ๊ธฐ๋ณธ ์ง๋ ฌํ๋ฅผ ์ํํ๋ค.
public final class Period implements Serializable {
private Date start;
private Date end;
public Period(Date start, Date end) {
this.start = new Date(start.getTime()); // ๋ฐฉ์ด์ ๋ณต์ฌ
this.end = new Date(end.getTime());
if (this.start.compareTo(this.end) > 0) { // ์ ํจ์ฑ ๊ฒ์ฌ
throw new IllegalArgumentException(start + " after " + end);
}
}
public Date start() {
return new Date(start.getTime());
}
public Date end() {
return new Date(end.getTime());
}
}
- ์๋์ ๊ฐ์ ๋ฐ์ดํธ์คํธ๋ฆผ์ผ๋ก Period ๊ฐ์ฒด๋ก ์ญ์ง๋ ฌํํ๋ค๋ฉด?
public class BogusPeriod {
// ๋ถ๋ณ์์ ๊นจ๋จ๋ฆฌ๋๋ก ์กฐ์๋ ๋ฐ์ดํธ ์คํธ๋ฆผ
private static final byte[] serializedForm = {
(byte)0xac, (byte)0xed, 0x00, 0x05, 0x73, 0x72, 0x00, 0x06,
0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x40, 0x7e, (byte)0xf8,
0x2b, 0x4f, 0x46, (byte)0xc0, (byte)0xf4, 0x02, 0x00, 0x02,
0x4c, 0x00, 0x03, 0x65, 0x6e, 0x64, 0x74, 0x00, 0x10, 0x4c,
0x6a, 0x61, 0x76, 0x61, 0x2f, 0x75, 0x74, 0x69, 0x6c, 0x2f,
0x44, 0x61, 0x74, 0x65, 0x3b, 0x4c, 0x00, 0x05, 0x73, 0x74,
0x61, 0x72, 0x74, 0x71, 0x00, 0x7e, 0x00, 0x01, 0x78, 0x70,
0x73, 0x72, 0x00, 0x0e, 0x6a, 0x61, 0x76, 0x61, 0x2e, 0x75,
0x74, 0x69, 0x6c, 0x2e, 0x44, 0x61, 0x74, 0x65, 0x68, 0x6a,
(byte)0x81, 0x01, 0x4b, 0x59, 0x74, 0x19, 0x03, 0x00, 0x00,
0x78, 0x70, 0x77, 0x08, 0x00, 0x00, 0x00, 0x66, (byte)0xdf,
0x6e, 0x1e, 0x00, 0x78, 0x73, 0x71, 0x00, 0x7e, 0x00, 0x03,
0x77, 0x08, 0x00, 0x00, 0x00, (byte)0xd5, 0x17, 0x69, 0x22,
0x00, 0x78
};
public static void main(String[] args) {
Period p = (Period) deserialize(serializedForm);
System.out.println(p.start);
System.out.println(p.end);
}
static Object deserialize(byte[] sf) {
try {
return new ObjectInputStream(new ByteArrayInputStream(sf)).readObject();
} catch (IOException | ClassNotFoundException e) {
throw new IllegalArgumentException(e);
}
}
}
- ์ ๋ฐ์ดํธ์คํธ๋ฆผ์ ์ ๋ณด๋, start ์ ์๊ฐ์ด end ์ ์๊ฐ๋ณด๋ค ๋๋ฆฌ๊ฒ ์กฐ์ํ๋ค.
- ์ฆ, ๋ถ๋ณ์์ ๊บ ๋จ๋ฆฐ ๊ฐ์ฒด๋ก ์ญ์ง๋ ฌํํ๋๋ก ์กฐ์๋์๋ค.
Fri Jan 01 12:00:00 PST 1999 // start ๊ฐ ๋ ๋๋ฆฌ๋ค.
Sun Jan 01 12:00:00 PST 1984 // end ๊ฐ ๋ ์ด๋ฅด๋ค.
- readObject ๋ฅผ ์ ์ํ๊ณ , ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ์ค์ํ๋ค.
- Period ํด๋์ค์ ๋ค์์ ๋ฉ์๋๋ฅผ ์ถ๊ฐํ๋ค.
private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
s.defaultReadObject(); // ๊ธฐ๋ณธ ์ง๋ ฌํ ์ํ
if (start.compareTo(end) > 0) { // ์ ํจ์ฑ ๊ฒ์ฌ
throw new InvalidObjectException(start + " ๊ฐ " + end + " ๋ณด๋ค ๋ฆ์ ์ ์์ต๋๋ค.");
}
}
- ์ง๋ ฌํ๋ ๋ฐ์ดํธ ์คํธ๋ฆผ ๋์ private Date ํ๋๋ก์ ์ฐธ์กฐ๋ฅผ ์ถ๊ฐํ๋ฉด ๊ฐ๋ณ Period ์ธ์คํด์ค๋ฅผ ๋ง๋ค ์ ์๋ค.
public class MutablePeriod {
public final Period period;
public final Date start;
public final Date end;
public MutablePeriod() {
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bos);
// ๋ถ๋ณ์์ ์ ์งํ๋ Period ๋ฅผ ์ง๋ ฌํ.
out.writeObject(new Period(new Date(), new Date()));
/*
* ์
์์ ์ธ start, end ๋ก์ ์ฐธ์กฐ๋ฅผ ์ถ๊ฐ.
*/
byte[] ref = { 0x71, 0, 0x7e, 0, 5 }; // ์
์์ ์ธ ์ฐธ์กฐ
bos.write(ref); // ์์ ํ๋
ref[4] = 4; // ์
์์ ์ธ ์ฐธ์กฐ
bos.write(ref); // ์ข
๋ฃ ํ๋
// ์ญ์ง๋ ฌํ ๊ณผ์ ์์ Period ๊ฐ์ฒด์ Date ์ฐธ์กฐ๋ฅผ ํ์น๋ค.
ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));
period = (Period) in.readObject();
start = (Date) in.readObject();
end = (Date) in.readObject();
} catch (IOException | ClassNotFoundException e) {
throw new AssertionError(e);
}
}
}
public static void main(String[] args) {
MutablePeriod mp = new MutablePeriod();
Period mutablePeriod = mp.period; // ๋ถ๋ณ ๊ฐ์ฒด๋ก ์์ฑํ Period
Date pEnd = mp.end; // MutablePeriod ํด๋์ค์ end ํ๋
pEnd.setYear(78); // MutablePeriod ์ end ๋ฅผ ๋ฐ๊ฟจ๋๋ฐ ?
System.out.println(mutablePeriod.end()); // Period ์ ๊ฐ์ด ๋ฐ๋๋ค.
pEnd.setYear(69);
System.out.println(mutablePeriod.end());
}
- ๊ฒฐ๊ณผ
Fri Apr 07 19:59:32 KST 1978
Mon Apr 07 19:59:32 KST 1969
- ๋ถ๋ณ ๊ฐ์ฒด Period ๋ฅผ ์ง๋ ฌํ / ์ญ์ง๋ ฌํํ๋ค๊ณ ์๊ฐํ ์ ์์ง๋ง,
- ์์ ๋ฐฉ๋ฒ์ผ๋ก ๋ถ๋ณ์์ ๊นจ๋จ๋ฆด ์ ์๋ค.
- ์ค์ ๋ก String ์ด ๋ถ๋ณ์ด๋ผ๋ ์ฌ์ค์ ๊ธฐ๋ ๋ณด์ ๋ฌธ์ ๋ค์ด ์กด์ฌํ๋ค.
- ๊ฐ์ฒด๋ฅผ ์ญ์ง๋ ฌํํ ๋๋ ํด๋ผ์ด์ธํธ๊ฐ ์์ ํด์๋ ์๋๋ ๊ฐ์ฒด ์ฐธ์กฐ๋ฅผ ๊ฐ๋ ํ๋๋ฅผ ๋ชจ๋ ๋ฐฉ์ด์ ๋ณต์ฌํ๋ค.
- ๋ถ๋ณ ํด๋์ค ์์ ๋ชจ๋ private ๊ฐ๋ณ ์์๋ฅผ ๋ฐฉ์ด์ ๋ณต์ฌํ๋ค.
private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
s.defaultReadObject();
// ๋ฐฉ์ด์ ๋ณต์ฌ๋ฅผ ํตํด ์ธ์คํด์ค์ ํ๋๊ฐ ์ด๊ธฐํ
start = new Date(start.getTime());
end = new Date(end.getTime());
// ์ ํจ์ฑ ๊ฒ์ฌ
if (start.compareTo(end) > 0)
throw new InvalidObjectException(start +" after "+ end);
}
- ์ ํจ์ฑ ๊ฒ์ฌ๋ณด๋ค ๋จผ์ ๋ฐฉ์ด์ ๋ณต์ฌ
- ๋ฐ๋๋ผ๋ฉด, ์ ํจ์ฑ ๊ฒ์ฌ ์ดํ ๋ฐฉ์ด์ ๋ณต์ฌ ์ด์ ์ ๋ถ๋ณ์์ ๊นจ๋จ๋ฆด ํ์ด ์๊ธด๋ค. (item 50)
- final ํ๋๋ ๋ฐฉ์ด์ ๋ณต์ฌ๊ฐ ๋ถ๊ฐ๋ฅํ๋ฏ๋ก, ํ๋๋ฅผ final ์ด ์๋๊ฒ ํด์ผํจ.
transient ํ๋๋ฅผ ์ ์ธํ ๋ชจ๋ ํ๋์ ๊ฐ์ ๋งค๊ฐ๋ณ์
๋ก ๋ฐ์ ์ ํจ์ฑ ๊ฒ์ฌ ์์ด
ํ๋์ ๋์
ํ๋ public ์์ฑ์
๋ฅผ ์ถ๊ฐํด๋ ๊ด์ฐฎ์๊ฐ ?
- Yes -> ๊ธฐ๋ณธ readObject
- No -> readObject ์ง์ ์ ์ ํ ์ ํจ์ฑ ๊ฒ์ฌ์ ๋ฐฉ์ด์ ๋ณต์ฌ ์ํ. or ์ง๋ ฌํ ํ๋ก์ ํจํด์ฌ์ฉ.
- readObject ๋ฉ์๋์์ ์ฌ์ ์ ๊ฐ๋ฅ ๋ฉ์๋๋ฅผ ํธ์ถํ๋ฉด ์๋๋ค. (item 19)
- ํด๋์ค๊ฐ final ์ด ์๋ ๊ฒฝ์ฐ์๋ง ํด๋น
- ์ด ํด๋์ค์ ํ์ ํด๋์ค๊ฐ ๋ถ๋ฆฌ๊ธฐ ์ด์ ์ ์์ฑ์์ ์ฌ์ ์๋ ๋ฉ์๋๊ฐ ์คํ๋๋ฏ๋ก ์ค๋ฅ๋ฅผ ๋ฑ๊ฒ ๋ ๊ฒ์ด๋ค.