BOOK/JAVA

μ΄νŽ™ν‹°λΈŒ μžλ°” : μš©μ–΄ 정리 & μ΄ν•΄λΆˆκ°€ ꡬ문 해석

devJK93 2024. 12. 29.

πŸ“š 1. μ‹œκ·Έλ‹ˆμ²˜

μ΄νŽ™ν‹°λΈŒ μžλ°”(Effective Java)μ—μ„œ μ–ΈκΈ‰ν•˜λŠ” μ‹œκ·Έλ‹ˆμ²˜(signature)λŠ” 주둜 λ©”μ„œλ“œ μ‹œκ·Έλ‹ˆμ²˜λ₯Ό μ˜λ―Έν•©λ‹ˆλ‹€. λ©”μ„œλ“œ μ‹œκ·Έλ‹ˆμ²˜λŠ” μžλ°”μ—μ„œ λ©”μ„œλ“œλ₯Ό μ‹λ³„ν•˜κ³  κ΅¬λΆ„ν•˜λŠ” 데 μ‚¬μš©λ˜λŠ” μ€‘μš”ν•œ μš”μ†Œλ‘œ, λ‹€μŒκ³Ό 같은 ꡬ성 μš”μ†Œλ‘œ 이루어져 μžˆμŠ΅λ‹ˆλ‹€:

  1. λ©”μ„œλ“œ 이름(Method Name): λ©”μ„œλ“œμ˜ 이름 자체.
  2. λ§€κ°œλ³€μˆ˜ λͺ©λ‘(Parameter List): λ©”μ„œλ“œκ°€ λ°›λŠ” λ§€κ°œλ³€μˆ˜μ˜ νƒ€μž…κ³Ό μˆœμ„œ.

λ©”μ„œλ“œ μ‹œκ·Έλ‹ˆμ²˜μ— ν¬ν•¨λ˜μ§€ μ•ŠλŠ” μš”μ†Œ:

  • λ°˜ν™˜ νƒ€μž…(Return Type): λ©”μ„œλ“œκ°€ λ°˜ν™˜ν•˜λŠ” κ°’μ˜ νƒ€μž…μ€ μ‹œκ·Έλ‹ˆμ²˜μ— ν¬ν•¨λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
  • μ˜ˆμ™Έ(Exception): λ©”μ„œλ“œκ°€ 던질 수 μžˆλŠ” μ˜ˆμ™Έλ„ μ‹œκ·Έλ‹ˆμ²˜μ˜ 일뢀가 μ•„λ‹™λ‹ˆλ‹€.
  • μ ‘κ·Ό μ œμ–΄μž(Access Modifiers): public, private λ“± μ ‘κ·Ό μ œμ–΄μžλŠ” μ‹œκ·Έλ‹ˆμ²˜μ— 영ν–₯을 주지 μ•ŠμŠ΅λ‹ˆλ‹€.

μ‹œκ·Έλ‹ˆμ²˜μ˜ μ€‘μš”μ„±

  1. λ©”μ„œλ“œ μ˜€λ²„λ‘œλ”©(Method Overloading):
    • 같은 이름을 가진 μ—¬λŸ¬ λ©”μ„œλ“œλ₯Ό μ •μ˜ν•  λ•Œ, μ‹œκ·Έλ‹ˆμ²˜κ°€ 달라야 μ»΄νŒŒμΌλŸ¬κ°€ 이λ₯Ό ꡬ뢄할 수 μžˆμŠ΅λ‹ˆλ‹€.
    • 예λ₯Ό λ“€μ–΄, void print(String s)와 void print(int i)λŠ” λ‹€λ₯Έ μ‹œκ·Έλ‹ˆμ²˜λ₯Ό κ°€μ§€λ―€λ‘œ μ˜€λ²„λ‘œλ”©μ΄ κ°€λŠ₯ν•©λ‹ˆλ‹€.
  2. λ©”μ„œλ“œ μ˜€λ²„λΌμ΄λ”©(Method Overriding):
    • μ„œλΈŒν΄λž˜μŠ€μ—μ„œ 슈퍼클래슀의 λ©”μ„œλ“œλ₯Ό μž¬μ •μ˜ν•  λ•Œ, μ‹œκ·Έλ‹ˆμ²˜κ°€ 동일해야 ν•©λ‹ˆλ‹€.
    • μ‹œκ·Έλ‹ˆμ²˜κ°€ λ‹€λ₯΄λ©΄ μ˜€λ²„λΌμ΄λ”©μ΄ μ•„λ‹Œ μƒˆλ‘œμš΄ λ©”μ„œλ“œλ‘œ μΈμ‹λ©λ‹ˆλ‹€.
  3. 컴파일러의 μ—­ν• :
    • μ»΄νŒŒμΌλŸ¬λŠ” λ©”μ„œλ“œ 호좜 μ‹œ μ‹œκ·Έλ‹ˆμ²˜λ₯Ό 기반으둜 μ–΄λ–€ λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν• μ§€ κ²°μ •ν•©λ‹ˆλ‹€.
    • μ‹œκ·Έλ‹ˆμ²˜κ°€ λͺ…ν™•ν•˜μ§€ μ•ŠμœΌλ©΄ 컴파일 였λ₯˜κ°€ λ°œμƒν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μ˜ˆμ‹œ

public class Example {
    // λ©”μ„œλ“œ μ‹œκ·Έλ‹ˆμ²˜: calculate(int a, int b)
    public int calculate(int a, int b) {
        return a + b;
    }

    // λ©”μ„œλ“œ μ‹œκ·Έλ‹ˆμ²˜: calculate(double a, double b)
    public double calculate(double a, double b) {
        return a + b;
    }

    // μ‹œκ·Έλ‹ˆμ²˜κ°€ λ‹€λ₯Έ λ©”μ„œλ“œμ΄λ―€λ‘œ μ˜€λ²„λ‘œλ”© κ°€λŠ₯
}

μœ„μ˜ μ˜ˆμ‹œμ—μ„œ 두 calculate λ©”μ„œλ“œλŠ” λ§€κ°œλ³€μˆ˜μ˜ νƒ€μž…μ΄ λ‹€λ₯΄κΈ° λ•Œλ¬Έμ— μ„œλ‘œ λ‹€λ₯Έ μ‹œκ·Έλ‹ˆμ²˜λ₯Ό 가지고 있으며, μ΄λŠ” λ©”μ„œλ“œ μ˜€λ²„λ‘œλ”©μ„ κ°€λŠ₯ν•˜κ²Œ ν•©λ‹ˆλ‹€.

μ‹œκ·Έλ‹ˆμ²˜ 섀계 μ‹œ 고렀사항

  • λͺ…ν™•μ„±: λ©”μ„œλ“œ 이름과 λ§€κ°œλ³€μˆ˜λŠ” λ©”μ„œλ“œμ˜ κΈ°λŠ₯을 λͺ…ν™•ν•˜κ²Œ ν‘œν˜„ν•΄μ•Ό ν•©λ‹ˆλ‹€.
  • 일관성: λΉ„μŠ·ν•œ κΈ°λŠ₯을 ν•˜λŠ” λ©”μ„œλ“œλŠ” μœ μ‚¬ν•œ μ‹œκ·Έλ‹ˆμ²˜λ₯Ό κ°€μ Έμ•Ό ν•©λ‹ˆλ‹€.
  • κ³Όλ„ν•œ μ˜€λ²„λ‘œλ”© ν”Όν•˜κΈ°: λ„ˆλ¬΄ λ§Žμ€ μ˜€λ²„λ‘œλ”©μ€ μ½”λ“œμ˜ 가독성을 λ–¨μ–΄λœ¨λ¦΄ 수 μžˆμœΌλ―€λ‘œ 적절히 μ‚¬μš©ν•΄μ•Ό ν•©λ‹ˆλ‹€.

μ΄νŽ™ν‹°λΈŒ μžλ°”μ—μ„œλŠ” λ©”μ„œλ“œ μ‹œκ·Έλ‹ˆμ²˜μ˜ μ€‘μš”μ„±μ„ κ°•μ‘°ν•˜λ©°, 이λ₯Ό 톡해 μ½”λ“œμ˜ μœ μ§€λ³΄μˆ˜μ„±κ³Ό 가독성을 λ†’μ΄λŠ” λ‹€μ–‘ν•œ 팁과 ꢌμž₯사항을 μ œκ³΅ν•©λ‹ˆλ‹€. μ‹œκ·Έλ‹ˆμ²˜λ₯Ό μ˜¬λ°”λ₯΄κ²Œ μ„€κ³„ν•¨μœΌλ‘œμ¨ 버그λ₯Ό 쀄이고, μ½”λ“œμ˜ μ˜λ„λ₯Ό λͺ…ν™•νžˆ 전달할 수 μžˆμŠ΅λ‹ˆλ‹€.


 

❓1. μΈν„°νŽ˜μ΄μŠ€μ™€ 정적 λ©”μ„œλ“œ (p.10)

μžλ°” 8 μ΄μ „μ—λŠ” μΈν„°νŽ˜μ΄μŠ€μ— 정적 λ©”μ„œλ“œ(static method)λ₯Ό 직접 μ„ μ–Έν•  수 μ—†μ—ˆμŠ΅λ‹ˆλ‹€. 이둜 인해 νŠΉμ • μΈν„°νŽ˜μ΄μŠ€λ₯Ό λ°˜ν™˜ν•˜λŠ” 정적 λ©”μ„œλ“œκ°€ ν•„μš”ν•  λ•ŒλŠ” λͺ‡ 가지 우회 방법을 μ‚¬μš©ν•΄μ•Ό ν–ˆμŠ΅λ‹ˆλ‹€. μ•„λž˜μ—μ„œ 이λ₯Ό μ‰½κ²Œ μ„€λͺ…ν•΄ λ“œλ¦¬κ² μŠ΅λ‹ˆλ‹€.

1. μΈν„°νŽ˜μ΄μŠ€μ™€ 정적 λ©”μ„œλ“œμ˜ ν•œκ³„

μΈν„°νŽ˜μ΄μŠ€λŠ” μžλ°”μ—μ„œ ν΄λž˜μŠ€κ°€ 따라야 ν•  계약(contract)을 μ •μ˜ν•©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄, List μΈν„°νŽ˜μ΄μŠ€λŠ” λ¦¬μŠ€νŠΈκ°€ κ°€μ Έμ•Ό ν•  λ©”μ„œλ“œλ“€μ„ μ •μ˜ν•©λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ μžλ°” 8 μ΄μ „μ—λŠ” μΈν„°νŽ˜μ΄μŠ€ 내뢀에 정적 λ©”μ„œλ“œλ₯Ό μ •μ˜ν•  수 μ—†μ—ˆμŠ΅λ‹ˆλ‹€.

2. λ™λ°˜ 클래슀(Companion Class) μ‚¬μš©

μΈν„°νŽ˜μ΄μŠ€μ— 정적 λ©”μ„œλ“œλ₯Ό 직접 μ •μ˜ν•  수 μ—†μ—ˆκΈ° λ•Œλ¬Έμ—, μΈν„°νŽ˜μ΄μŠ€μ™€ κ΄€λ ¨λœ 정적 λ©”μ„œλ“œλ₯Ό λͺ¨μ•„두기 μœ„ν•΄ λ™λ°˜ 클래슀λ₯Ό λ§Œλ“€μ—ˆμŠ΅λ‹ˆλ‹€. 이 λ™λ°˜ ν΄λž˜μŠ€λŠ” 보톡 μΈν„°νŽ˜μ΄μŠ€ 이름에 "s"λ₯Ό 뢙인 ν˜•νƒœλ‘œ, μΈμŠ€ν„΄μŠ€ν™”ν•  수 μ—†λŠ” 클래슀둜 λ§Œλ“­λ‹ˆλ‹€.

μ˜ˆμ‹œ:

public interface Type {
    // μΈν„°νŽ˜μ΄μŠ€ λ©”μ„œλ“œλ“€
}

public final class Types {
    // μΈμŠ€ν„΄μŠ€ 생성을 λ°©μ§€ν•˜κΈ° μœ„ν•΄ private μƒμ„±μž μ‚¬μš©
    private Types() {}

    // Type μΈν„°νŽ˜μ΄μŠ€λ₯Ό λ°˜ν™˜ν•˜λŠ” 정적 λ©”μ„œλ“œ
    public static Type createType() {
        return new TypeImpl();
    }
}

 

μ—­ν• : Types ν΄λž˜μŠ€λŠ” Type μΈν„°νŽ˜μ΄μŠ€μ™€ κ΄€λ ¨λœ 정적 λ©”μ„œλ“œλ“€μ„ λͺ¨μ•„놓은 λ™λ°˜ 클래슀(Companion Class) μž…λ‹ˆλ‹€.

νŠΉμ§•:

  • final ν‚€μ›Œλ“œλ‘œ μ„ μ–Έλ˜μ–΄ 상속할 수 μ—†μŠ΅λ‹ˆλ‹€.
  • private μƒμ„±μžλ₯Ό 가지고 μžˆμ–΄ μ™ΈλΆ€μ—μ„œ μΈμŠ€ν„΄μŠ€λ₯Ό 생성할 수 μ—†μŠ΅λ‹ˆλ‹€.
  • λͺ¨λ“  λ©”μ„œλ“œλŠ” static으둜 μ„ μ–Έλ˜μ–΄ μžˆμ–΄ 클래슀 이름을 톡해 직접 ν˜ΈμΆœν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μœ„ μ˜ˆμ‹œμ—μ„œ Types ν΄λž˜μŠ€λŠ” μΈμŠ€ν„΄μŠ€ν™”ν•  수 μ—†μœΌλ©°, Type μΈν„°νŽ˜μ΄μŠ€λ₯Ό λ°˜ν™˜ν•˜λŠ” 정적 λ©”μ„œλ“œλ₯Ό μ œκ³΅ν•©λ‹ˆλ‹€.

3. μžλ°” μ»¬λ ‰μ…˜ ν”„λ ˆμž„μ›Œν¬μ˜ 예

μžλ°” μ»¬λ ‰μ…˜ ν”„λ ˆμž„μ›Œν¬λŠ” λ‹€μ–‘ν•œ 자료ꡬ쑰(리슀트, 집합, 맡 λ“±)λ₯Ό μ œκ³΅ν•˜λ©°, 이듀 λŒ€λΆ€λΆ„μ€ java.util.Collections ν΄λž˜μŠ€μ— μ •μ˜λœ 정적 νŒ©ν† λ¦¬ λ©”μ„œλ“œλ₯Ό 톡해 μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€. 이 ν΄λž˜μŠ€λŠ” μΈμŠ€ν„΄μŠ€ν™”ν•  수 μ—†λŠ” 클래슀둜, λͺ¨λ“  λ©”μ„œλ“œκ°€ 정적 λ©”μ„œλ“œμž…λ‹ˆλ‹€.

μ˜ˆμ‹œ:

List synchronizedList = Collections.synchronizedList(new ArrayList<>());

μœ„ μ˜ˆμ‹œμ—μ„œ Collections.synchronizedListλŠ” List μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•œ λ™κΈ°ν™”λœ 리슀트λ₯Ό λ°˜ν™˜ν•˜λŠ” 정적 λ©”μ„œλ“œμž…λ‹ˆλ‹€. 이λ₯Ό 톡해 μΈν„°νŽ˜μ΄μŠ€μ— 직접 정적 λ©”μ„œλ“œλ₯Ό μ •μ˜ν•˜μ§€ μ•Šκ³ λ„ ν•„μš”ν•œ κΈ°λŠ₯을 μ œκ³΅ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

4. μ™œ λ™λ°˜ 클래슀λ₯Ό μ‚¬μš©ν–ˆμ„κΉŒ?

  • 쑰직화: κ΄€λ ¨λœ 정적 λ©”μ„œλ“œλ₯Ό ν•˜λ‚˜μ˜ ν΄λž˜μŠ€μ— λͺ¨μ•„두어 μ½”λ“œκ°€ κΉ”λ”ν•˜κ³  κ΄€λ¦¬ν•˜κΈ° μ‰½μŠ΅λ‹ˆλ‹€.
  • μΈμŠ€ν„΄μŠ€ν™” 방지: λ™λ°˜ ν΄λž˜μŠ€λŠ” μΈμŠ€ν„΄μŠ€λ₯Ό 생성할 ν•„μš”κ°€ μ—†κΈ° λ•Œλ¬Έμ—, private μƒμ„±μžλ₯Ό μ‚¬μš©ν•˜μ—¬ μΈμŠ€ν„΄μŠ€ 생성을 λ§‰μŠ΅λ‹ˆλ‹€.
  • μœ μ§€λ³΄μˆ˜ 용이: μΈν„°νŽ˜μ΄μŠ€μ™€ κ΄€λ ¨λœ 정적 λ©”μ„œλ“œκ°€ λ³„λ„μ˜ ν΄λž˜μŠ€μ— μ‘΄μž¬ν•˜λ―€λ‘œ, κΈ°λŠ₯ μΆ”κ°€λ‚˜ μˆ˜μ •μ΄ μš©μ΄ν•©λ‹ˆλ‹€.

5. μžλ°” 8 μ΄ν›„μ˜ λ³€ν™”

μžλ°” 8λΆ€ν„°λŠ” μΈν„°νŽ˜μ΄μŠ€μ— 정적 λ©”μ„œλ“œλ₯Ό 직접 μ •μ˜ν•  수 있게 λ˜μ—ˆμŠ΅λ‹ˆλ‹€. 이λ₯Ό 톡해 λ™λ°˜ 클래슀λ₯Ό μ‚¬μš©ν•˜λŠ” λ²ˆκ±°λ‘œμ›€μ„ 쀄일 수 μžˆμŠ΅λ‹ˆλ‹€.

μ˜ˆμ‹œ:

public interface Type {
    // μΈν„°νŽ˜μ΄μŠ€ λ©”μ„œλ“œλ“€

    // μžλ°” 8 이후 정적 λ©”μ„œλ“œ
    static Type createType() {
        return new TypeImpl();
    }
}

μœ„μ™€ 같이 μΈν„°νŽ˜μ΄μŠ€ 내뢀에 정적 λ©”μ„œλ“œλ₯Ό 직접 μ •μ˜ν•  수 있게 λ˜μ–΄, κ΄€λ ¨λœ κΈ°λŠ₯을 ν•œ 곳에 λͺ¨μ•„λ‘λŠ” 것이 λ”μš± κ°„νŽΈν•΄μ‘ŒμŠ΅λ‹ˆλ‹€.

μš”μ•½

  • μžλ°” 8 이전: μΈν„°νŽ˜μ΄μŠ€μ— 정적 λ©”μ„œλ“œλ₯Ό μ •μ˜ν•  수 μ—†μ–΄μ„œ, λ³„λ„μ˜ λ™λ°˜ 클래슀λ₯Ό λ§Œλ“€μ–΄ 정적 λ©”μ„œλ“œλ₯Ό κ΄€λ¦¬ν–ˆμŠ΅λ‹ˆλ‹€.
  • μ˜ˆμ‹œ: java.util.Collections ν΄λž˜μŠ€λŠ” μ»¬λ ‰μ…˜ μΈν„°νŽ˜μ΄μŠ€μ— κ΄€λ ¨λœ λ‹€μ–‘ν•œ 정적 λ©”μ„œλ“œλ₯Ό μ œκ³΅ν•˜μ—¬, μΈν„°νŽ˜μ΄μŠ€ 자체λ₯Ό λ°˜ν™˜ν•˜κ±°λ‚˜ λ³€ν˜•λœ μ»¬λ ‰μ…˜μ„ 생성할 수 있게 ν–ˆμŠ΅λ‹ˆλ‹€.
  • μžλ°” 8 이후: μΈν„°νŽ˜μ΄μŠ€μ— 정적 λ©”μ„œλ“œλ₯Ό 직접 μ •μ˜ν•  수 있게 λ˜μ–΄, λ™λ°˜ 클래슀의 ν•„μš”μ„±μ΄ μ€„μ–΄λ“€μ—ˆμŠ΅λ‹ˆλ‹€.

이해λ₯Ό 돕기 μœ„ν•œ λΉ„μœ λ₯Ό λ“€μ–΄λ³΄κ² μŠ΅λ‹ˆλ‹€. μΈν„°νŽ˜μ΄μŠ€λŠ” 섀계도라고 생각할 수 있고, λ™λ°˜ ν΄λž˜μŠ€λŠ” 섀계도에 κΈ°λ°˜ν•œ 도ꡬ함이라고 ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 도ꡬ함 μ•ˆμ—λŠ” 섀계도λ₯Ό κ΅¬ν˜„ν•˜κ±°λ‚˜ ν™•μž₯ν•˜λŠ” 데 ν•„μš”ν•œ 도ꡬ듀이 λ“€μ–΄μžˆμŠ΅λ‹ˆλ‹€. μžλ°” 8 μ΄μ „μ—λŠ” 섀계도(μΈν„°νŽ˜μ΄μŠ€) μžμ²΄μ— 도ꡬ(정적 λ©”μ„œλ“œ)λ₯Ό 넣을 수 μ—†μ—ˆκΈ° λ•Œλ¬Έμ—, λ³„λ„μ˜ 도ꡬ함(λ™λ°˜ 클래슀)을 λ§Œλ“€μ–΄ μ‚¬μš©ν–ˆλ˜ κ²ƒμž…λ‹ˆλ‹€.

λŒ“κΈ€