item 41 SeungminLee - JAVA-JIKIMI/EFFECTIVE-JAVA3 GitHub Wiki
item 41
μ μνλ €λ κ²μ΄ νμ μ΄λΌλ©΄ λ§μ»€ μΈν°νμ΄μ€λ₯Ό μ¬μ©νλΌ
μ무 λ©μλλ λ΄κ³ μμ§ μκ³ , λ¨μ§ μμ μ ꡬννλ ν΄λμ€κ° νΉμ μμ±μ κ°μ§μ νμν΄μ£Όλ μΈν°νμ΄μ€λ₯Ό λ§μ»€μΈν°νμ΄μ€ λΌκ³ νλ€. Serializable μΈν°νμ΄μ€κ° μ’μ μλ€. Serializableμ μμ μ ꡬνν ν΄λμ€μ μΈν°νμ΄μ€λ ObjectOutputStreamμ ν΅ν΄ μΈ μ μλ€κ³ (μ§λ ¬ν ν μ μλ€κ³ ) μλ €μ€λ€.
* @author unascribed
* @see java.io.ObjectOutputStream
* @see java.io.ObjectInputStream
* @see java.io.ObjectOutput
* @see java.io.ObjectInput
* @see java.io.Externalizable
* @since JDK1.1
*/
public interface Serializable {
}
λ§μ»€ μ λν μ΄μ μ΄ λ±μ₯νλ©΄μ λ§μ»€ μΈν°νμ΄μ€λ ꡬμμ΄ λμλ€κ³ νμ§λ§ μ΄λ μ¬μ€μ΄ μλλ€. λ§μ»€ μΈν°νμ΄μ€λ μλμ κ°μ μν©μμ λ§μ»€ μ λν μ΄μ λ³΄λ€ λ«λ€.
- λ§μ»€ μΈν°νμ΄μ€λ μ΄λ₯Ό ꡬνν ν΄λμ€μ μΈμ€ν΄μ€λ€μ ꡬλΆνλ νμ μΌλ‘ μΈ μ μμΌλ, λ§μ»€ μ λν μ΄μ μ κ·Έλ μ§ μλ€.
- μ μ© λμμ λ μ λ°νκ² μ§μ ν μ μλ€.
λ§μ»€ μ λν μ΄μ @Test
@Retention(value=RUNTIME)
@Target(value=METHOD)
public @interface Test
μ무 맀κ°λ³μ μμ΄ λ¨μν λμμ λ§νΉνλ€ (item 39)
λ§μ»€ μΈν°νμ΄μ€λ μ΄λ₯Ό ꡬνν ν΄λμ€μ μΈμ€ν΄μ€λ€μ ꡬλΆνλ νμ μΌλ‘ μΈ μ μμΌλ λ§μ»€ μ λν μ΄μ μ κ·Έλ μ§ μλ€.
λ§μ»€ μΈν°νμ΄μ€λ μ΄μΏν νμ μ΄κΈ° λλ¬Έμ, λ§μ»€ μ λν μ΄μ μ μ¬μ©νλ€λ©΄ λ°νμμ λ°κ²¬λ μ€λ₯λ₯Ό μ»΄νμΌ νμμ μ‘μ μ μλ€.
/**
* Underlying writeObject/writeUnshared implementation.
*/
private void writeObject0(Object obj, boolean unshared)
throws IOException
{
boolean oldMode = bout.setBlockDataMode(false);
depth++;
try {
// handle previously written and non-replaceable objects
int h;
if ((obj = subs.lookup(obj)) == null) {
writeNull();
return;
} else if (!unshared && (h = handles.lookup(obj)) != -1) {
writeHandle(h);
return;
} else if (obj instanceof Class) {
writeClass((Class) obj, unshared);
return;
} else if (obj instanceof ObjectStreamClass) {
writeClassDesc((ObjectStreamClass) obj, unshared);
return;
}
// check for replacement object
Object orig = obj;
Class<?> cl = obj.getClass();
ObjectStreamClass desc;
for (;;) {
// REMIND: skip this check for strings/arrays?
Class<?> repCl;
desc = ObjectStreamClass.lookup(cl, true);
if (!desc.hasWriteReplaceMethod() ||
(obj = desc.invokeWriteReplace(obj)) == null ||
(repCl = obj.getClass()) == cl)
{
break;
}
cl = repCl;
}
if (enableReplace) {
Object rep = replaceObject(obj);
if (rep != obj && rep != null) {
cl = rep.getClass();
desc = ObjectStreamClass.lookup(cl, true);
}
obj = rep;
}
// if object replaced, run through original checks a second time
if (obj != orig) {
subs.assign(orig, obj);
if (obj == null) {
writeNull();
return;
} else if (!unshared && (h = handles.lookup(obj)) != -1) {
writeHandle(h);
return;
} else if (obj instanceof Class) {
writeClass((Class) obj, unshared);
return;
} else if (obj instanceof ObjectStreamClass) {
writeClassDesc((ObjectStreamClass) obj, unshared);
return;
}
}
// remaining cases
if (obj instanceof String) {
writeString((String) obj, unshared);
} else if (cl.isArray()) {
writeArray(obj, desc, unshared);
} else if (obj instanceof Enum) {
writeEnum((Enum<?>) obj, desc, unshared);
} else if (obj instanceof Serializable) {
writeOrdinaryObject(obj, desc, unshared);
} else {
if (extendedDebugInfo) {
throw new NotSerializableException(
cl.getName() + "\n" + debugInfoStack.toString());
} else {
throw new NotSerializableException(cl.getName());
}
}
} finally {
depth--;
bout.setBlockDataMode(oldMode);
}
}
Serializable μΈν°νμ΄μ€λ₯Ό μ¬μ©νλ©΄ ObjectOutputStream.writeObject 맀μλμμ Seralizable μ ꡬννμ§ μμ κ°μ²΄λ₯Ό λ°μΌλ©΄ μ»΄νμΌ νμμ μ€λ₯κ° λλ€. μ΄μ²λΌ λ§μ»€ μΈν°νμ΄μ€λ μ€λ₯λ₯Ό μ»΄νμΌ νμμ μ‘μ μ μμ§λ§ λ§μ»€ μ λν μ΄μ μ μΈ κ²½μ° λ°μλ μ€λ₯λ₯Ό λ°νμμ κ°μμΌ μ‘μ μ μλ€.
λ§μ»€ μΈν°νμ΄μ€κ° λμ μ λ λ²μ§Έλ μ μ© λμμ λ μ λ°νκ² μ§μ ν μ μλ€.
μ μ© λμ(@Target)μ Element.TYPE μΌλ‘ μ μΈν μλν μ΄μ μ λͺ¨λ νμ (ν΄λμ€, μΈν°νμ΄μ€, μ΄κ±°νμ , μ λν μ΄μ )μ λ¬ μ μλ€. λΆμ°©ν μ μλ νμ μ λ μΈλ°νκ² μ¬ννμ§λ λͺ»νλ€λ λ»μ΄λ€.
package java.lang.annotation;
public enum ElementType {
TYPE,
FIELD,
METHOD,
PARAMETER,
CONSTRUCTOR,
LOCAL_VARIABLE,
ANNOTATION_TYPE,
PACKAGE,
TYPE_PARAMETER,
TYPE_USE,
MODULE;
private ElementType() {
}
}
νΉμ μΈν°νμ΄μ€λ₯Ό ꡬνν ν΄λμ€μλ§ μ μ©νκ³ μΆμ λ§μ»€κ° μλ€κ³ ν΄λ³΄μ. μ΄ λ§μ»€λ₯Ό μΈν°νμ΄μ€λ‘ μ μνλ€λ©΄ κ·Έλ₯ λ§νΉνκ³ μΆμ ν΄λμ€μμλ§ κ·Έ μΈν°νμ΄μ€λ₯Ό ꡬννλ©΄ λλ€. κ·Έλ¬λ©΄ λ§νΉλ νμ μ μλμΌλ‘ κ·Έ μΈν°νμ΄μ€μ νμ νμ μμ΄ λ³΄μ₯λλ κ²μ΄λ€.
Set μΈν°νμ΄μ€λ μΌμ’ μ λ§μ»€ μΈν°νμ΄μ€λ‘ λ³Ό μ μλ€.
- Collection νμ νμ μλ§ μ μ©ν μ μλ€.
- Collectionμ΄ μ μν add, equals, hashCode λ±μ λ©μλ μΈμλ μλ‘ μΆκ°ν κ²μ΄ μλ€.
- μ΄λ° λ§μ»€ μΈν°νμ΄μ€λ κ°μ²΄μ νΉμ λΆλΆμ λΆλ³μμΌλ‘ κ·μ νκ±°λ κ·Έ νμ μ μΈμ€ν΄μ€λ λ€λ₯Έ ν΄λμ€μ νΉμ λ©μλκ° μ²λ¦¬ν μ μλ€λ μ¬μ€μ λͺ μνλ μ©λλ‘ μ¬μ©ν μ μλ€. (ex: Serializable μΈν°νμ΄μ€λ ObjectOutPutStreamμ΄ μ²λ¦¬ν μ μλ μΈμ€ν΄μ€)
λ°λλ‘ λ§μ»€ μ λν μ΄μ μ΄ λ§μ»€ μΈν°νμ΄μ€λ³΄λ€ λμ μ μΌλ‘λ κ±°λν μ λν μ΄μ μμ€ν μ μ§μμ λ°λλ€λ μ μ λ€ μ μλ€. λ°λΌμ μ λν μ΄μ μ μ κ·Ή νμ©νλ νλ μμν¬μμλ λ§μ»€ μ λν μ΄μ μ μ°λ μͺ½μ΄ μΌκ΄μ±μ μ§ν€λλ° μ 리ν κ²μ΄λ€.
κ·Έλ λ€λ©΄ μ΄λ€ λμ λ§μ»€ μ λν μ΄μ μ, λ μ΄λ€ λμ λ§μ»€ μΈν°νμ΄μ€λ₯Ό μ¨μΌν κΉ?
-
ν΄λμ€μ μΈν°νμ΄μ€ μΈμ νλ‘κ·Έλ¨ μμλ€(λͺ¨λ, ν¨ν€μ§, νλ, μ§μλ³μ λ±)μ λ§νΉμ ν΄μΌ ν λ μ λν μ΄μ μ μΈ μλ°μ μλ€. λ§μ»€ μΈν°νμ΄μ€λ₯Ό μ¬μ©νλ©΄ μΈν°νμ΄μ€λ₯Ό ꡬνν μ μλ ν΄λμ€μ μΈν°νμ΄μ€λ§ μ¬μ©μ΄ κ°λ₯νκΈ° λλ¬Έμ΄λ€.
-
μ λν μ΄μ μ νλ°ν νμ©νλ νλ μμν¬μμ μ¬μ©νλ λ§μ»€λΌλ©΄ λ§μ»€ μ λν μ΄μ μ μ¬μ©νλ νΈμ΄ μ’μ κ²μ΄λ€.
-
λ§μ»€λ₯Ό μΈν°νμ΄μ€λ ν΄λμ€μ μ μ©ν΄μΌ νλ€λ©΄?
"μ΄ λ§νΉμ΄ λ κ°μ²΄λ₯Ό 맀κ°λ³μλ‘ λ°λ λ©μλλ₯Ό μμ±ν μΌμ΄ μμκΉ?" λΌκ³ μλ¬Έν΄λ³΄μ.
'κ·Έλ λ€' β λ§μ»€ μΈν°νμ΄μ€λ₯Ό μ¨μΌνλ€. κ·Έ λ§μ»€ μΈν°νμ΄μ€λ₯Ό ν΄λΉ λ©μλμ 맀κ°λ³μ νμ μΌλ‘ μ¬μ©νμ¬ μ»΄νμΌ νμμ μ€λ₯λ₯Ό μ‘μλΌ μ μλ€.
'κ·Έλ° μΌμ μ λ μλ€' β μλ§λ λ§μ»€ μ λν μ΄μ μ΄ λμ μ νμ΄λ€.
sum up
λ§μ»€ μΈν°νμ΄μ€μ λ§μ»€ μ λν μ΄μ μ κ°μμ μ°μμ΄ μλ€. μλ‘ μΆκ°νλ λ©μλ μμ΄ λ¨μ§ νμ μ μκ° λͺ©μ μ΄λΌλ©΄ λ§μ»€ μΈν°νμ΄μ€λ₯Ό μ¬μ©νμ. μ μ© λμμ΄ ElementType.TYPEμΈ λ§μ»€ μ λν μ΄μ μ μμ±νκ³ μλ€λ©΄, μ μ μ¬μ λ₯Ό κ°μ§κ³ μ λ§ μ λν μ΄μ μΌλ‘ ꡬννλκ² μ³μμ§, νΉμ λ§μ»€ μΈν°νμ΄μ€κ° λ«μ§λ μμμ§ κ³°κ³°μ΄ μκ°ν΄λ³΄μ.