item 87 SeungminLee - JAVA-JIKIMI/EFFECTIVE-JAVA3 GitHub Wiki
๊ฐ๋ฐ ์ผ์ ์ ์ซ๊ธฐ๋ ์ํฉ์ด๋ผ ์ด๋ฒ ๋ฆด๋ฆฌ์ค์์๋ ๊ทธ๋ฅ ๋์๋ง ํ๋๋ก ๋ง๋ค์ด ๋๊ณ ๋ค์ ๋ฆด๋ฆฌ์ฆ์์ ์ ๋๋ก ๊ตฌํ์ ํ๋๊ฒ ์ข ์ข ์ผ์ด๋์ง๋ง ํด๋์ค๊ฐ Serializable์ ๊ตฌํํ๊ณ ๊ธฐ๋ณธ ์ง๋ ฌํ ํํ๋ฅผ ์ฌ์ฉํ๋ค๋ฉด ๋ค์ ๋ฆด๋ฆฌ์ค ๋ ๋ฒ๋ฆฌ๋ ค ํ ํ์ฌ์ ๊ตฌํ์ ์์ํ ๋ฐ์ด ๋ฌถ์ด๊ฒ ๋๋ค.
- ๊ธฐ๋ณธ ์ง๋ ฌํ ํํ๋ ์ ์ฐ์ฑ, ์ฑ๋ฅ, ์ ํ์ฑ ์ธก๋ฉด์์ ์ ์คํ ๊ณ ๋ฏผํ ํ ํฉ๋นํ ๋๋ง ์ฌ์ฉํด์ผ ํ๋ค.
- ๊ธฐ๋ณธ ์ง๋ ฌํ ํํ๋ ๊ฐ์ฒด๊ฐ ํฌํจํ ๋ฐ์ดํฐ๋ค๊ณผ ๊ทธ ๊ฐ์ฒด์์๋ถํฐ ์์ํด ์ ๊ทผํ ์ ์๋ ๋ชจ๋ ๊ฐ์ฒด๋ฅผ ๋ด์๋ด๋จ, ์ฌ์ง์ด ์ด ๊ฐ์ฒด๋ค์ด ์ฐ๊ฒฐ๋ ์์๊น์ง ๊ธฐ์ ํ๋ค.
- ๋ฐ๋ฉด ์ด์์ ์ธ ์ง๋ ฌํ ํํ๋ ๋ฌผ๋ฆฌ์ ์ธ ๋ชจ์ต๊ณผ ๋ ๋ฆฝ๋ ๋ ผ๋ฆฌ์ ์ธ ๋ชจ์ต๋ง์ ํํํด์ผ ํ๋ค.
๊ฐ์ฒด์ ๋ฌผ๋ฆฌ์ ํํ๊ณผ ๋ ผ๋ฆฌ์ ๋ด์ฉ์ด ๊ฐ๋ค๋ฉด ๊ธฐ๋ณธ ์ง๋ ฌํ ํํ๋ผ๋ ๋ฌด๋ฐฉํ๋ค.
public class Name implements Serializable {
/**
* ์ฑ. null์ด ์๋์ด์ผํจ
* @serial
*/
private final String lastName;
/**
* ์ด๋ฆ. null์ด ์๋์ด์ผ ํจ.
* @serial
*/
private final String firstName;
/**
* ์ค๊ฐ์ด๋ฆ. ์ค๊ฐ์ด๋ฆ์ด ์๋ค๋ฉด null.
* @serial
*/
private final String middleName;
}
- ์ฑ๋ช ์ ๋ ผ๋ฆฌ์ ์ผ๋ก ์ด๋ฆ, ์ฑ, ์ค๊ฐ์ด๋ฆ์ด๋ผ๋ 3๊ฐ์ ๋ฌธ์์ด๋ก ๊ตฌ์ฑ๋๋ฉฐ, ์ ์ฝ๋์ ์ธ์คํด์ค ํ๋๋ค์ ์ด ๋ ผ๋ฆฌ์ ๊ตฌ์ฑ์์๋ฅผ ์ ํํ๊ฒ ๋ฐ์ํ๊ธฐ ๋๋ฌธ์ ๊ธฐ๋ณธ ์ง๋ ฌํ๋ฅผ ์ฌ์ฉํด๋ ๋ฌด๋ฐฉํ๋ค.
- ์ธ ํ๋ ๋ชจ๋ private์์๋ ๋ฌธ์ํ ์ฃผ์์ด ๋ฌ๋ ค์๋ค. ์ด ํ๋๋ค์ ๊ฒฐ๊ตญ ํด๋์ค์ ์ง๋ ฌํ ํํ์ ํฌํจ๋๋ ๊ณต๊ฐ API์ ์ํ๊ธฐ ๋๋ฌธ์ด๋ค.
๊ธฐ๋ณธ ์ง๋ ฌํ ํํ๊ฐ ์ ํฉํ๋ค๊ณ ๊ฒฐ์ ํ๋๋ผ๋ ๋ถ๋ณ์ ๋ณด์ฅ๊ณผ ๋ณด์์ ์ํ readObject ๋ฉ์๋๋ฅผ ์ ๊ณตํด์ผ ํ ๋๊ฐ ๋ง๋ค.
์์ Name ํด๋์ค์ ๊ฒฝ์ฐ์๋ readObject ๋ฉ์๋๊ฐ lastName๊ณผ firstName ํ๋๊ฐ null์ด ์๋์ ๋ณด์ฅํด์ผ ํ๋ค.
public final class StringList implements Serializable {
private int size = 0;
private Entry head = null;
private static class Entry implements Serializable {
String data;
Entry next;
Entry previous;
}
}
์ด ํด๋์ค๋ ์ง๋ ฌํ ํํ์ ์ ํฉํ์ง ์๋ค.
๋ ผ๋ฆฌ์ ์ผ๋ก ์ด ํด๋์ค๋ ์ผ๋ จ์ ๋ฌธ์์ด์ ํํํ๋ค. ๋ฌผ๋ฆฌ์ ์ผ๋ก๋ ๋ฌธ์์ด๋ค์ ์ด์ค ์ฐ๊ฒฐ ๋ฆฌ์คํธ๋ก ์ฐ๊ฒฐํ๊ธฐ ๋๋ฌธ์ด๋ค.
์ด ํด๋์ค์ ๊ธฐ๋ณธ ์ง๋ ฌํ ํํ๋ฅผ ์ฌ์ฉํ๋ฉด ๊ฐ ๋ ธ๋์ ์๋ฐฉํฅ ์ฐ๊ฒฐ ์ ๋ณด๋ฅผ ํฌํจํด ๋ชจ๋ Entry ๋ฅผ ์ฒ ๋์ฒ ๋ฏธํ๊ฒ ๊ธฐ๋กํ๋ค.
๊ฐ์ฒด์ ๋ฌผ๋ฆฌ์ ํํ๊ณผ ๋ ผ๋ฆฌ์ ํํ์ ์ฐจ์ด๊ฐ ํด ๋ ๊ธฐ๋ณธ ์ง๋ ฌํ ํํ๋ฅผ ์ฌ์ฉํ๋ฉด ํฌ๊ฒ ๋ค ๊ฐ์ง ๋ฉด์์ ๋ฌธ์ ๊ฐ ์๊ธด๋ค.
- ๊ณต๊ฐ API๊ฐ ํ์ฌ์ ๋ด๋ถ ํํ ๋ฐฉ์์ ์๊ตฌํ ๋ฌถ์ธ๋ค.
- ๋๋ฌด ๋ง์ ๊ณต๊ฐ์ ์ฐจ์งํ ์ ์๋ค.
- ์๊ฐ์ด ๋๋ฌด ๋ง์ด ๊ฑธ๋ฆด ์ ์๋ค.
์ง๋ ฌํ ๋ก์ง์ ๊ฐ์ฒด ๊ทธ๋ํ์์์์ ๊ดํ ์ ๋ณด๊ฐ ์์ผ๋ ๊ทธ๋ํ๋ฅผ ์ง์ ์ํํด ๋ณผ ์ ๋ฐ์ ์๋ค.
- ์คํ ์ค๋ฒํ๋ก๋ฅผ ์ผ์ผํฌ ์ ์๋ค.
public final class StringList implements Serializable {
private transient int size = 0;
private transient Entry head = null;
// ์ด์ ๋ ์ง๋ ฌํ๋์ง ์๋๋ค.
private static class Entry {
String data;
Entry next;
Entry previous;
}
// ์ง์ ํ ๋ฌธ์์ด์ ์ด ๋ฆฌ์คํธ์ ์ถ๊ฐํ๋ค.
public final void add(String s) {...}
/**
* ์ด {@code StringList} ์ธ์คํด์ค๋ฅผ ์ง๋ ฌํํ๋ค.
*
* @serialData ์ด ๋ฆฌ์คํธ์ ํฌ๊ธฐ(ํฌํจ๋ ๋ฌธ์์ด์ ๊ฐ์)๋ฅผ ๊ธฐ๋กํ ํ
* ({@code int}), ์ด์ด์ ๋ชจ๋ ์์๋ฅผ(๊ฐ๊ฐ์ {@code String})
* ์์๋๋ก ๊ธฐ๋กํ๋ค.
*/
private void writeObject(ObjectOutputStream s) throws IOException {
//๊ธฐ๋ณธ ์ง๋ ฌํ๋ฅผ ์ํํ๋ค.
s.defaultWriteObject();
s.writeInt(size);
// ์ปค์คํ
์ญ์ง๋ ฌํ๋ฅผ ์ํํ๋ค.
// ๋ชจ๋ ์์๋ฅผ ์ฌ๋ฐ๋ฅธ ์์๋ก ๊ธฐ๋กํ๋ค.
for (Entry e = head; e != null; e = e.next)
s.writeObject(e.data);
}
private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
//๊ธฐ๋ณธ ์ญ์ง๋ ฌํ๋ฅผ ์ํํ๋ค.
s.defaultReadObject();
int numElements = s.readInt();
// ์ปค์คํ
์ญ์ง๋ ฌํ ๋ถ๋ถ
// ๋ชจ๋ ์์๋ฅผ ์ฝ์ด ์ด ๋ฆฌ์คํธ์ ์ฝ์
ํ๋ค.
for(int i = 0; i < numElements; i++) {
add((String) s.readObject());
}
}
}
transient: ํด๋น ์ธ์คํด์ค ํ๋๊ฐ ๊ธฐ๋ณธ ์ง๋ ฌํ ํํ์ ํฌํจ๋์ง ์๋๋ค๋ ํ์
- StringList๋ฅผ ์ํ ํฉ๋ฆฌ์ ์ธ ์ง๋ ฌํ ํํ๋ ๋จ์ํ ๋ฆฌ์คํธ๊ฐ ํฌํจํ ๋ฌธ์์ด์ ๊ฐ์๋ฅผ ์ ์ ๋ค์, ๊ทธ ๋ค์ค ๋ฌธ์์ด๋ค์ ๋์ดํ๋ ์์ค์ด๋ฉด ๋ ๊ฒ์ด๋ค. StringList์ ๋ฌผ๋ฆฌ์ ์ธ ์์ธ ํํ์ ๋ฐฐ์ ํ ์ฑ ๋ ผ๋ฆฌ์ ์ธ ๊ตฌ์ฑ๋ง ๋ด๋ ๊ฒ์ด๋ค.
- writeObject์ readObject๊ฐ ์ง๋ ฌํ๋ฅผ ์ฒ๋ฆฌํ๋ฉฐ StringList์ ํ๋๊ฐ ๋ชจ๋ transient๋๋ผ๋ ์ ๋์ ๊ฐ๊ฐ ๊ฐ์ฅ ๋จผ์ defaultWriteObject์ defaultReadObject๋ฅผ ํธ์ถํ๋ค.
- ์ง๋ ฌํ ๋ช ์ธ๋ ์ด ์์ ์ ๋ฌด์กฐ๊ฑด ํด์ผ ํฅํ ๋ฆด๋ฆฌ์ค์์ transient๊ฐ ์๋ ์ธ์คํด์ค ํ๋๊ฐ ์ถ๊ฐ๋๋๋ผ๋ ์ํธ ํธํ์ด ๋๊ธฐ ๋๋ฌธ์ด๋ค.
- ์ด์ ๊ฐ์ ์์ด๋ผ๋ฉด StringList ์ง๋ ฌํ ํํ๋ ์๋ ๋ฒ์ ์ ์ ๋ฐ ์ ๋์ ๊ณต๊ฐ์ ์ฐจ์งํ๋ฉฐ ์คํ๋๋ ์๋๋ ๋ ๋ฐฐ ์ ๋ ๋น ๋ฅด๊ฒ ์ํํ๋ค.
- ์คํ ์ค๋ฒํ๋ก๋ ์ ํ ๋ฐ์ํ์ง ์์ ์ค์ง์ ์ผ๋ก ์ง๋ ฌํ ํ ์ ์๋ ํฌ๊ธฐ ์ ํ์ด ์์ด์ก๋ค.
StringList์์๋ ๊ธฐ๋ณธ ์ง๋ ฌํ ํํ๋ ๋น๋ก ์ ์ฐ์ฑ๊ณผ ์ฑ๋ฅ์ด ๋จ์ด์ก๋๋ผ๊ณ , ๊ฐ์ฒด๋ฅผ ์ง๋ ฌํํ ํ ์ญ์ง๋ ฌํํ๋ฉด ์๋ ๊ฐ์ฒด๋ฅผ ๊ทธ ๋ถ๋ณ์๊น์ง ํฌํจํด ์ ๋๋ก ๋ณต์ํด๋ธ๋ค๋ ์ ์์ ์ ํํ๋ค๊ณ ํ ์ ์์ง๋ง ๋ถ๋ณ์์ด ์ธ๋ถ ๊ตฌํ์ ๋ฐ๋ผ ๋ฌ๋ผ์ง๋ ๊ฐ์ฒด์์๋ ์ด ์ ํ์ฑ๋ง์ ๊นจ์ง ์ ์๋ค.
ํด์ํ ์ด๋ธ์ ์๋ก ์๊ฐํด๋ณด์.
- ํด์ํ ์ด๋ธ์ ๋ฌผ๋ฆฌ์ ์ผ๋ก๋ ํค-๊ฐ ์ํธ๋ฆฌ๋ค์ ๋ด์ ํด์ ๋ฒํท์ ์ฐจ๋ก๋ก ๋์ดํ ํํ๋ค.
- ์ด๋ค ์ํธ๋ฆฌ๋ฅผ ์ด๋ค ๋ฒํท์ ๊ฐ์์ง๋ ํค์์ ๊ตฌํ ํด์์ฝ๋๊ฐ ๊ฒฐ์ ํ๋๋ฐ, ๊ทธ ๊ณ์ฐ ๋ฐฉ์์ ๊ตฌํ์ ๋ฐ๋ผ ๋ฌ๋ผ์ง ์ ์๋ค. ์ฌ์ง์ด ๊ณ์ฐํ ๋๋ง๋ค ๋ฌ๋ผ์ง๊ธฐ๋ ํ๋ค.
- ๋๋ฌธ์ ํด์ํ ์ด๋ธ์ ์ง๋ ฌํํ ํ ์ญ์ง๋ ฌํํ๋ฉด ๋ถ๋ณ์์ด ์ฌ๊ฐํ๊ฒ ํผ์๋ ๊ฐ์ฒด๋ค์ด ์๊ฒจ๋ ์ ์๋ ๊ฒ์ด๋ค.
ํด๋น ๊ฐ์ฒด์ ๋ ผ๋ฆฌ์ ์ํ์ ๋ฌด๊ดํ ํ๋๋ผ๊ณ ํ์ ํ ๋๋ง transient ํ์ ์๋ฅผ ์๋ตํด์ผ ํ๋ค.
๊ทธ๋์ ์ปค์คํ ์ง๋ ฌํ ํํ๋ฅผ ์ฌ์ฉํ๋ค๋ฉด, ์์์ StringList ์์์์ฒ๋ผ ๋๋ถ๋ถ์ ์ธ์คํด์ค ํ๋๋ฅผ transient๋ก ์ ์ธํด์ผ ํ๋ค.
- ๊ธฐ๋ณธ ์ง๋ ฌํ๋ฅผ ์ฌ์ฉํ๋ฉด transient ํ๋๋ค์ ์ญ์ง๋ ฌํ ๋ ๋ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ด๊ธฐํ๋จ์ ์์ง ๋ง์.
- ๊ธฐ๋ณธ๊ฐ์ ๊ทธ๋๋ก ์ฌ์ฉํด์๋ ์๋๋ค๋ฉด readObject ๋ฉ์๋์์ defaultReadObject๋ฅผ ํธ์ถํ ๋ค์, ํด๋น ํ๋๋ฅผ ์ํ๋ ๊ฐ์ผ๋ก ๋ณต์ํ์. ํน์ ๊ทธ ๊ฐ์ ์ฒ์ ์ฌ์ฉํ ๋ ์ด๊ธฐํ ํ๋ ๋ฐฉ๋ฒ๋ ์๋ค.
๊ฐ์ฒด์ ์ ์ฒด ์ํ๋ฅผ ์ฝ๋ ๋ฉ์๋์ ์ ์ฉํด์ผ ํ๋ ๋๊ธฐํ ๋ฉ์ปค๋์ฆ์ ์ง๋ ฌํ์๋ ์ ์ฉํด์ผ ํ๋ค.
private synchronized void writeObject(ObjectOutputStream s) throws IOException {
s.defaultWriteObject();
}
sunchronized๋ก ์ ์ธํ์ฌ ์ค๋ ๋ ์์ ํ๊ฒ ๋ง๋ ๊ฐ์ฒด์์ ๊ธฐ๋ณธ ์ง๋ ฌํ๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด writeObject๋ ์์ฒ๋ผ synchronized๋ก ์ ์ธํด์ผ ํ๋ค.
- writeObject ๋ฉ์๋ ์์์ ๋๊ธฐํ ํ๊ณ ์ถ๋ค๋ฉด ํด๋์ค์ ๋ค๋ฅธ ๋ถ๋ถ์์ ์ฌ์ฉํ๋ ๋ฝ ์์๋ฅผ ๋๊ฐ์ด ๋ฐ๋ผ์ผ ํ๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด ์์ ์์ ๊ต์ฐฉ์ํ์ ๋น ์ง ์ ์๋ค.
์ด๋ค ์ง๋ ฌํ ํํ๋ฅผ ํํ๋ ์ง๋ ฌํ ๊ฐ๋ฅ ํด๋์ค ๋ชจ๋์ ์ง๋ ฌ ๋ฒ์ UID๋ฅผ ๋ช ์์ ์ผ๋ก ๋ถ์ฌํ์.
์ด๋ ๊ฒ ํ๋ฉด ์ง๋ ฌ ๋ฒ์ ผ UID๊ฐ ์ผ์ผํค๋ ์ ์ฌ์ ์ธ ํธํ์ฑ ๋ฌธ์ ๊ฐ ์ฌ๋ผ์ง๋ค. ์ฑ๋ฅ๋ ์กฐ๊ธ ๋นจ๋ผ์ง๋๋ฐ, ์ง๋ ฌ ๋ฒ์ ผ UID๋ฅผ ๋ช ์ํ์ง ์์ผ๋ฉด ๋ฐํ์์ ์ด ๊ฐ์ ์์ฑํ๋๋ผ ๋ณต์กํ ์ฐ์ฐ์ ์ํํ๊ธฐ ๋๋ฌธ์ด๋ค.
private static final long serialVersionUID = -232923283928929;
์๋ก ์์ฑํ๋ ํด๋์ค์์๋ ์ด๋ค long๊ฐ์ ์ ํํ๋ ์๊ด์๋ค. ๊ทธ๋ฅ ์๊ฐ๋๋ ์๋ฌด ๊ฐ์ด๋ ์ ํํด๋ ๋๋ค.
์ง๋ ฌ ๋ฒ์ ผ UID๊ฐ ์๋ ๊ธฐ์กด ํด๋์ค๋ฅผ ๊ตฌ๋ฒ์ ์ผ๋ก ์ง๋ ฌํ๋ ์ธ์คํด์ค์ ํธํ์ฑ์ ์ ์งํ ์ฑ ์์ ํ๊ณ ์ถ๋ค๋ฉด, ๊ตฌ๋ฒ์ ์์ ์ฌ์ฉํ ์๋ ์์ฑ๋ ๊ฐ์ ๊ทธ๋๋ก ์ฌ์ฉํด์ผ ํ๋ค. ๊ธฐ๋ณธ ๋ฒ์ ํด๋์ค์์ ํธํ์ฑ์ ๋๊ณ ์ถ๋ค๋ฉด ๋จ์ํ ์ง๋ ฌ ๋ฒ์ UID๊ฐ์ ๋ฐ๊ฟ์ฃผ๋ฉด ๋๋ค.
๊ตฌ๋ฒ์ ์ผ๋ก ์ง๋ ฌํ๋ ์ธ์คํด์ค๋ค๊ณผ์ ํธํ์ฑ์ ๋์ผ๋ ค๋ ๊ฒฝ์ฐ๋ฅผ ์ ์ธํ๊ณ ๋ ์ง๋ ฌ ๋ฒ์ UID๋ฅผ ์ ๋ ์์ ํ์ง ๋ง์.
- ํด๋์ค๋ฅผ ์ง๋ ฌํํ๊ธฐ๋ก ํ๋ค๋ฉด ์ด๋ค ์ง๋ ฌํ ํํ๋ฅผ ์ฌ์ฉํ ์ง ์ฌ์ฌ์์กฐ ํ๊ธฐ
- ์๋ฐ์ ๊ธฐ๋ณธ ์ง๋ ฌํ ํํ๋ ๊ฐ์ฒด๋ฅผ ์ง๋ ฌํํ ๊ฒฐ๊ณผ๊ฐ ํด๋น ๊ฐ์ฒด์ ๋ ผ๋ฆฌ์ ํํ์ ๋ถํฉํ ๋๋ง ์ฌ์ฉํ๊ณ ๊ทธ๋ ์ง ์๋ค๋ฉด ์ปค์คํ ์ง๋ ฌํ ํํ๋ฅผ ๊ณ ์ํ๋ผ.
- ์ง๋ ฌํ ํํ๋ ๊ณต๊ฐ ๋ฉ์๋๋ฅผ ์ค๊ณํ ๋์ ์คํ๋ ์๊ฐ์ ๋ค์ฌ ์ค๊ณํด์ผ ํ๋ค.
- ํ๋ฒ ๊ณต๊ฐ๋ ๋ฉ์๋๋ ํฅํ ๋ฆด๋ฆฌ์ค์์ ์ ๊ฑฐํ ์ ์๋ฏ์ด, ์ง๋ ฌํ ํํ์ ํฌํจ๋ ํ๋๋ ๋ง์๋๋ก ์ ๊ฑฐํ ์ ์๋ค.
- ์๋ชป๋ ์ง๋ ฌํ ํํ๋ฅผ ์ ํํ๋ฉด ํด๋น ํด๋์ค์ ๋ณต์ก์ฑ๊ณผ ์ฑ๋ฅ์ ์๊ตฌํ ๋ถ์ ์ ์ธ ์ํฅ์ ๋จ๊ธด๋ค.