readObject ๋ฉ์๋๋ ๋ฐฉ์ด์ ์ผ๋ก ์์ฑํ๋ผ
๋
ผ๋ฆฌ์ /๋ฌผ๋ฆฌ์ ํํ์ด ๋ถํฉํ์ฌ ๊ธฐ๋ณธ ์ง๋ ฌํ ํํ๋ฅผ ์ฌ์ฉํด๋ ๊ด์ฐฎ์ ๊ฒ ์ฒ๋ผ ๋ณด์ด์ง๋ง, ๋ถ๋ณ์์ ๋ณด์ฅํด์ผ ํ๋ ๊ฒฝ์ฐ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์๋ค.
public final class Period implements Serializable {
private final Date start;
private final 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());
}
// ...
}
์ด์ ๋ readObject
๊ฐ ์ค์ง์ ์ผ๋ก ๋ ๋ค๋ฅธ public ์์ฑใ
๋ฐ ์ญํ ์ ํ๊ธฐ ๋๋ฌธ์, ์์ฑ์์์ ํ๋ ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ readObject
์์๋ ์ํํด์ผ ํ๋ค.
๋ณดํต์ ์ ์์ ์ผ๋ก ์์ฑ๋ ์ธ์คํด์ค๋ก ๋ฐ์ดํธ ์คํธ๋ฆผ์ ์์ฑํด์ ๋ฌธ์ ๊ฐ ์์ง๋ง, ์์๋ก ์์ฑ๋ ๋ฐ์ดํธ ์คํธ๋ฆผ์ ์ญ์ง๋ ฌํํ ์ ์๊ธฐ ๋๋ฌธ์ ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ์ํํด์ผ ํ๋ค.
private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
s.defaultReadObject();
// ์ ํจ์ฑ ๊ฒ์ฌ
if (start.compareTo(end) > 0) {
throw new InvalidObjectException(start + " after " + end);
}
}
์์ฑ์์ readObject
๋ฉ์๋์์ ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ์ํํ๋ฉด, ๋ถ๋ณ์์ ์์ ํ ๋ณด์ฅํ ์ ์๋ ๊ฒ์ฒ๋ผ ๋ณด์ด์ง๋ง, ๋ค๋ฅธ ์ฌ์ด๋ ์ดํํธ๊ฐ ๋ฐ์ํ ์ ์๋ค.
์๋ ์์๋ ์ ์ Period
์ธ์คํด์ค์์ ์์๋ ๋ฐ์ดํธ ์คํธ๋ฆผ ๋์ 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()));
// ์
์์ ์ธ ์ด์ ๊ฐ์ฒด ์ฐธ์กฐ
// ์ด๋ฏธ ์ง๋ ฌํ๋ ๊ฐ์ฒด์ธ Period ๋ด๋ถ์ Date ํ๋๋ก์ ์ฐธ์กฐ๋ฅผ ์ถ๊ฐ
byte[] ref = {0x71, 0, 0x7e, 0, 5};
bos.write(ref); // ์์ ํ๋
ref[4] = 4;
bos.write(ref); // ์ข
๋ฃ ํ๋
// Period ์ธ์คํด์ค ์ญ์ง๋ ฌํ
ObjectInputStream in = new ObjectInputStream(
new ByteArrayInputStream(bos.toByteArray()));
period = (Period) in.readObject();
start = (Date) in.readObject(); // Period ๋ด๋ถ์ Date ๊ฐ์ฒด ์ฐธ์กฐ
end = (Date) in.readObject(); // Period ๋ด๋ถ์ Date ๊ฐ์ฒด ์ฐธ์กฐ
// ๊ฒฐ๊ณผ์ ์ผ๋ก start์ end๋ period์ ๋ด๋ถ Date ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ๊ฒ ๋จ
} catch (Exception e) {
throw new AssertionError(e);
}
}
}
public class Main {
public static void main(String[] args) {
MutablePeriod mp = new MutablePeriod();
Period p = mp.period;
Date pEnd = mp.end; // pEnd๋ p์ ๋ด๋ถ Date ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐ
pEnd.setYear(78); // pEnd ๋ณ๊ฒฝ -> p๋ ํจ๊ป ๋ณ๊ฒฝ๋จ
System.out.println(p);
}
}
Period
์ธ์คํด์ค๋ ๋ถ๋ณ์ฑ์ ์ ์งํ ์ฑ ์์ฑ๋์ง๋ง, ๊ณต๊ฒฉ์๊ฐ ์๋์ ์ผ๋ก ๋ด๋ถ์ ๊ฐ์ ์์ ํ ์ ์๊ฒ ๋๊ณ , ์ด๋ Period
์ธ์คํด์ค์ ๋ถ๋ณ์ฑ์ ๊นจ๋จ๋ฆฌ๊ฒ ๋๋ค.
์ด๋ ๊ฐ์ฒด ์ฐธ์กฐ๋ฅผ ๊ฐ๋ ํ๋ ๋ชจ๋๋ฅผ ๋ฐฉ์ด์ ์ผ๋ก ๋ณต์ฌํ์ฌ ๋ฐฉ์งํ ์ ์๋ค.
private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
s.defaultReadObject();
// ๋ฐฉ์ด์ ๋ณต์ฌ, ์ฌํ ๋น์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ํ๋์ final ํค์๋๋ฅผ ์ฌ์ฉํ ์ ์์
start = new Date(start.getTime());
end = new Date(end.getTime());
// ์ ํจ์ฑ ๊ฒ์ฌ
if (start.compareTo(end) > 0) {
throw new InvalidObjectException(start + " after " + end);
}
}