β˜• μžλ°” : JAVA

[Effective Java] μƒμ„±μž λŒ€μ‹  정적 νŒ©ν„°λ¦¬ λ©”μ„œλ“œ μ‚¬μš©ν•˜κΈ°

개발자 HOON 2023. 1. 6. 16:03

 

λ³Έ 글은 μ΄νŽ™ν‹°λΈŒ μžλ°” 3νŒμ„ 읽고 μ •λ¦¬ν•œ κΈ€ μž…λ‹ˆλ‹€. λ™μΌν•œ λ‚΄μš©μ΄ 포함될 수 μžˆμŠ΅λ‹ˆλ‹€.

 

🏝0. μ„œλ‘ 

 

일반적으둜 클래슀의 μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜λŠ” 방식은, public μƒμ„±μžμž…λ‹ˆλ‹€.

λ‹€λ₯Έ λ°©μ‹μœΌλ‘œλŠ”, 정적 νŒ©ν† λ¦¬ λ©”μ„œλ“œ(static factory method)λ₯Ό λ§Œλ“€μ–΄ μ œκ³΅ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

이 정적 νŒ©ν† λ¦¬ λ©”μ„œλ“œλŠ” λ‹¨μˆœνžˆ ν•΄λ‹Ή 클래슀의 μΈμŠ€ν„΄μŠ€λ₯Ό λ°˜ν™˜ν•˜λŠ” 것이 κ·Έ μ—­ν• μ˜ μ „λΆ€μž…λ‹ˆλ‹€.

 

λ‹€μŒμ€ 정적 νŒ©ν† λ¦¬ λ©”μ„œλ“œμ˜ μ˜ˆμ‹œλ‘œ, Boolean 래퍼 클래슀의 valueOf λ©”μ†Œλ“œμž…λ‹ˆλ‹€.

public static Boolean valueOf(boolean b){
	return b ? Boolean.TRUE : Boolean.FALSE;
}

 

κ·Έλ ‡λ‹€λ©΄ 정적 νŒ©ν„°λ¦¬ λ©”μ†Œλ“œλ₯Ό μ‚¬μš©ν–ˆμ„ λ•Œμ˜ μž₯점은 λ¬΄μ—‡μΌκΉŒμš”?

 

 

πŸ€” 1. 정적 νŒ©ν† λ¦¬ λ©”μ„œλ“œμ˜ μž₯단점

1-1. μž₯점

 

1) 이름을 κ°€μ§ˆ 수 μžˆμŠ΅λ‹ˆλ‹€.

μƒμ„±μžλ₯Ό 톡해 μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜λŠ” κ²½μš°μ—λŠ”, 클래슀 이름을 λͺ…μ‹œν•˜κ³ , λ‚΄λΆ€μ˜ νŒŒλΌλ―Έν„°λ₯Ό μ‚½μž…ν•˜λŠ” λ°©μ‹μœΌλ‘œ μƒμ„±λ©λ‹ˆλ‹€. 이 κ²½μš°μ— λ°˜ν™˜λ  객체의 νŠΉμ„±μ„ μ •ν™•ν•˜κ²Œ μ„€λͺ…ν•  수 μ—†μŠ΅λ‹ˆλ‹€. λ°˜λ©΄μ— 정적 νŒ©ν„°λ¦¬ λ©”μ„œλ“œλŠ” 'λ©”μ„œλ“œ'이기 λ•Œλ¬Έμ— 고유의 이름을 κ°€μ§ˆ 수 μžˆμŠ΅λ‹ˆλ‹€.

 

new BigInteger(int, int, Random); // μƒμ„±μžλ‘œ μΈμŠ€ν„΄μŠ€ 생성
BigInteger.probablePrime(...); // 정적 νŒ©ν† λ¦¬ λ©”μ„œλ“œλ‘œ μΈμŠ€ν„΄μŠ€ 생성

 

μœ„μ˜ 두 μ½”λ“œλŠ” 결과적으둜 BigInteger νƒ€μž…μ˜ 객체λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€. ν•˜μ§€λ§Œ 두 경우 μ€‘μ—μ„œ "값이 μ†Œμˆ˜μΈ BigIntegerλ₯Ό λ°˜ν™˜ν•œλ‹€"λ₯Ό 더 잘 μ„€λͺ…ν•˜λŠ” μ½”λ“œλŠ” λ¬΄μ—‡μΌκΉŒμš”? 정적 νŒ©ν† λ¦¬ λ©”μ„œλ“œμ˜ 이름을 잘 μ§“λŠ”λ‹€λ©΄, 이λ₯Ό λ”μš± 더 잘 μ„€λͺ…ν•  수 μžˆμ„ κ²ƒμž…λ‹ˆλ‹€.

 

또 ν•˜λ‚˜μ˜ μ‹œκ·Έλ‹ˆμ²˜λ‘œλŠ” μƒμ„±μžλ₯Ό ν•˜λ‚˜λ§Œ λ§Œλ“€ 수 μžˆμŠ΅λ‹ˆλ‹€. μƒμ„±μžμ˜ μž…λ ₯ λ§€κ°œλ³€μˆ˜μ˜ μˆœμ„œλ₯Ό λ°”κΏ” μ˜€λ²„λΌμ΄λ”© ν•΄λ³΄κ² λ‹€λΌλŠ” μƒκ°μœΌλ‘œ μ œν•œμ„ ν”Όν•΄λ³Ό μˆ˜λŠ” μžˆκ² μ§€λ§Œ, μ–΄λ–€ 역할을 ν•˜λŠ”μ§€ ꡬ뢄할 수 μ—†μ–΄ 쒋은 λ°œμƒμ€ μ•„λ‹™λ‹ˆλ‹€.

λ”°λΌμ„œ ν•œ ν΄λž˜μŠ€μ— μ‹œκ·Έλ‹ˆμ²˜κ°€ 같은 μƒμ„±μžκ°€ μ—¬λŸ¬κ°œ ν•„μš”ν•œ 경우, 정적 νŒ©ν„°λ¦¬ λ©”μ„œλ“œλ₯Ό ν™œμš©ν•˜λŠ” 것은 ꡉμž₯히 효율적인 λ°©λ²•μž…λ‹ˆλ‹€.

 

 

2) 호좜될 λ•Œλ§ˆλ‹€ μΈμŠ€ν„΄μŠ€λ₯Ό μƒˆλ‘œ μƒμ„±ν•˜μ§€λŠ” μ•Šμ•„λ„ 됨

 

이 μž₯μ μ—μ„œ μœ μ‹¬νžˆ 보아야 ν•˜λŠ” 것은, 'μƒμ„±ν•˜μ§€λŠ”'이라고 ν‘œν˜„ν•œ κ²ƒμž…λ‹ˆλ‹€.

자주 μ‚¬μš©ν•˜λŠ” μΈμŠ€ν„΄μŠ€λ₯Ό 미리 λ§Œλ“€μ–΄ 놓고, μΊμ‹œμ— μ €μž₯ν•΄λ†“λŠ” λ°©λ²•μœΌλ‘œ, μƒˆλ‘œ μƒμ„±ν•˜μ§€ μ•Šκ³  λ°˜ν™˜ν•˜λŠ” λ°©μ‹μœΌλ‘œ 정적 νŒ©ν† λ¦¬ λ©”μ„œλ“œλ₯Ό ν™œμš©ν•  수 μžˆλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€.

 

μƒμ„±μžλ₯Ό μ‚¬μš©ν•œλ‹€λ©΄, 이런 κ²½μš°λŠ” μ•„μ˜ˆ λΆˆκ°€λŠ₯ν•˜μ£ .

μœ„μ—μ„œ 예λ₯Ό λ“€μ—ˆλ˜, Boolean.valueOf(boolean) λ©”μ„œλ“œλŠ” μƒˆλ‘œμš΄ 객체λ₯Ό μ•„μ˜ˆ μƒμ„±ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. 

    public static final Boolean TRUE = new Boolean(true);
    public static final Boolean FALSE = new Boolean(false);
    
    public static Boolean valueOf(boolean b) {
        return (b ? TRUE : FALSE);
    }

Boolean.TRUE와 Boolean.FALSEλ₯Ό 미리 λΆˆλ³€ 객체둜 μƒμ„±ν•œ 후에, valueOf λ©”μ†Œλ“œλ‘œ ν•΄λ‹Ή λΆˆλ³€ 객체λ₯Ό λ¦¬ν„΄ν•©λ‹ˆλ‹€.

λ”°λΌμ„œ μƒμ„±μžλ₯Ό ν†΅ν•΄μ„œ Boolean 객체λ₯Ό μƒμ„±ν•˜λ©΄, μƒˆλ‘œμš΄ μΈμŠ€ν„΄μŠ€κ°€ μƒμ„±λ˜μ§€λ§Œ, valueOfλ₯Ό 톡해 Boolean 객체λ₯Ό μƒμ„±ν•˜λ©΄, μƒˆλ‘œμš΄ μΈμŠ€ν„΄μŠ€κ°€ μƒμ„±λœ 것이 μ•„λ‹ˆλΌ 이미 λ§Œλ“€μ–΄ 놓은 λΆˆλ³€ 객체λ₯Ό λ°˜ν™˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

 

이둜써 μƒˆλ‘œμš΄ 객체λ₯Ό μƒμ„±ν•˜λŠ” μ‹œκ°„μ , 곡간적 λΉ„μš©μ„ μ ˆμ•½ν•  수 μžˆλŠ” μž₯점이 μžˆμ–΄μ„œ 자주 μ‚¬μš©ν•˜λŠ” μΈμŠ€ν„΄μŠ€κ°€ μ •ν•΄μ Έ μžˆλŠ” κ²½μš°μ— μ‚¬μš©ν•˜λ©΄ λ§Žμ€ 이점을 λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€.

 

 

3) λ°˜ν™˜ νƒ€μž…μ˜ ν•˜μœ„ νƒ€μž… 객체λ₯Ό λ°˜ν™˜ν•  수 μžˆλŠ” λŠ₯λ ₯이 있음.

 

이 λŠ₯λ ₯은 λ°˜ν™˜ν•  객체의 클래슀λ₯Ό 자유둭게 선택할 수 μ—†λŠ” μ—„μ²­λ‚œ μœ μ—°μ„±μ„ μ œκ³΅ν•©λ‹ˆλ‹€.

상속과 λ‹€ν˜•μ„±μ— μ˜ν•΄ λ°˜ν™˜ νƒ€μž…μ˜ ν•˜μœ„ νƒ€μž… 객체λ₯Ό λ°˜ν™˜ν•  수 μžˆλ‹€λŠ” 것은 λ‹Ήμ—°ν•©λ‹ˆλ‹€.

 

λŒ€ν‘œμ μΈ μ˜ˆμ‹œλ‘œ, java.util.Collectionsμ—μ„œ 정적 νŒ©ν† λ¦¬ λ©”μ„œλ“œλ₯Ό ν†΅ν•΄μ„œ 총 45개의 μœ ν‹Έλ¦¬ν‹° κ΅¬ν˜„μ²΄λ₯Ό 얻을 수 μžˆμŠ΅λ‹ˆλ‹€. μ»¬λ ‰μ…˜ ν”„λ ˆμž„μ›Œν¬λŠ” 이 45개 클래슀λ₯Ό κ³΅κ°œν•˜μ§€ μ•ŠλŠ” λ°©μ‹μœΌλ‘œ API 외견을 훨씬 μž‘κ²Œ λ§Œλ“€ 수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€.

 

또 이 얻은 객체λ₯Ό κ΅¬ν˜„ ν΄λž˜μŠ€κ°€ μ•„λ‹Œ μΈν„°νŽ˜μ΄μŠ€λ§ŒμœΌλ‘œ λ‹€λ£° 수 μžˆμŠ΅λ‹ˆλ‹€.

 

 

4) μž…λ ₯ 맀개 λ³€μˆ˜μ— 따라 맀번 λ‹€λ₯Έ 클래슀의 객체λ₯Ό λ°˜ν™˜ν•  수 μžˆλ‹€.

 

λ°˜ν™˜ νƒ€μž…μ˜ ν•˜μœ„ νƒ€μž…μ΄κΈ°λ§Œ ν•˜λ©΄, μ–΄λ–€ 클래슀의 객체λ₯Ό λ°˜ν™˜ν•΄λ„ μƒκ΄€μ—†μŠ΅λ‹ˆλ‹€.

λ”°λΌμ„œ μž…λ ₯ λ§€κ°œλ³€μˆ˜μ˜ 쑰건을 λ”°λ₯Έ 객체λ₯Ό λ°˜ν™˜ν•΄λ„ 상관이 μ—†λ‹€λŠ” λœ»μž…λ‹ˆλ‹€.

 

예λ₯Ό λ“€λ©΄, EnumSet ν΄λž˜μŠ€λŠ” public μƒμ„±μž 없이 정적 νŒ©ν„°λ¦¬ λ©”μ†Œλ“œλ§Œ μ œκ³΅ν•œλ‹€κ³  ν•©λ‹ˆλ‹€.

OpenJDKμ—μ„œ μ‚¬μš©ν•˜λ©΄, μ›μ†Œμ˜ μˆ˜μ— λ”°λΌμ„œ 64개 μ΄ν•˜λ©΄ μ›μ†Œλ₯Ό long λ³€μˆ˜ ν•˜λ‚˜λ‘œ κ΄€λ¦¬ν•˜λŠ” RegularEnumSet μΈμŠ€ν„΄μŠ€λ₯Ό,

65개 이상이면 long λ°°μ—΄λ‘œ κ΄€λ¦¬ν•˜λŠ” JumboEnumSet의 μΈμŠ€ν„΄μŠ€λ₯Ό λ°˜ν™˜ν•œλ‹€κ³  ν•©λ‹ˆλ‹€.

 

μš°λ¦¬κ°€ EnumSet 클래슀λ₯Ό 정적 νŒ©ν† λ¦¬ λ©”μ†Œλ“œλ‘œ μƒμ„±ν•œλ‹€κ³  ν–ˆμ„ λ•Œ, μš°λ¦¬λŠ” 이 λ‚΄λΆ€ 쑴재λ₯Ό λͺ°λΌλ„ λ©λ‹ˆλ‹€.

ν•˜μœ„ 클래슀의 μ‚­μ œκ°€ μΌμ–΄λ‚˜λ„, μ„±λŠ₯을 κ°œμ„ ν•΄λ„, μƒˆλ‘œμš΄ ν•˜μœ„ ν΄λž˜μŠ€κ°€ 생겨도 μ „ν˜€ 지μž₯이 μ—†λ‹€λŠ” 것도 또 ν•˜λ‚˜μ˜ μž₯μ μž…λ‹ˆλ‹€.

κ·Έμ € ν•˜μœ„ 클래슀이기만 ν•˜λ©΄ λ©λ‹ˆλ‹€.

 

 

5) 정적 νŒ©ν† λ¦¬ λ©”μ„œλ“œλ₯Ό μž‘μ„±ν•˜λŠ” μ‹œμ μ—λŠ” λ°˜ν™˜ν•  객체의 ν΄λž˜μŠ€κ°€ μ‘΄μž¬ν•˜μ§€ μ•Šμ•„λ„ λœλ‹€.

 

이게 무슨 μ†Œλ¦¬μ•Ό..? ν΄λž˜μŠ€κ°€ μ‘΄μž¬ν•˜μ§€ μ•Šμ•„λ„ μž‘μ„±μ΄ κ°€λŠ₯ν•˜λ‹€λ‹ˆ?

μ•½κ°„ μ˜€ν•΄μ˜ μ†Œμ§€κ°€ μžˆμ„ μˆ˜λŠ” μžˆμŠ΅λ‹ˆλ‹€.

 

μ•„μ˜ˆ μ„ μ–Έν•œ 적 μ—†λŠ” 클래슀λ₯Ό 정적 νŒ©ν† λ¦¬ λ©”μ„œλ“œμ˜ 리턴 κ°’μœΌλ‘œ μ •μ˜ν•  수 μžˆλ‹€λŠ” 뜻이 μ•„λ‹ˆλΌ,

'μΈν„°νŽ˜μ΄μŠ€'λ₯Ό μƒμ„±ν•˜κ³  λ‚΄λΆ€ κ΅¬ν˜„μ²΄ 클래슀λ₯Ό κ΅¬ν˜„ν•˜μ§€ μ•Šμ€ μƒνƒœμ—μ„œ 정적 νŒ©ν† λ¦¬ λ©”μ„œλ“œμ˜ 리턴 κ°’μœΌλ‘œ μ‚¬μš©μ΄ κ°€λŠ₯ν•˜λ‹€λŠ” λœ»μž…λ‹ˆλ‹€.

 

 

1-2. 단점

 

1) 상속을 ν•˜λ €λ©΄ publicμ΄λ‚˜ protected μƒμ„±μžκ°€ ν•„μš”ν•˜λ―€λ‘œ 정적 νŒ©ν† λ¦¬ λ©”μ„œλ“œλ§Œ μ œκ³΅ν•œλ‹€λ©΄ ν•˜μœ„ 클래슀λ₯Ό λ§Œλ“€ 수 μ—†μŠ΅λ‹ˆλ‹€.

2) 정적 νŒ©ν„°λ¦¬ λ©”μ„œλ“œλ₯Ό ν”„λ‘œκ·Έλž˜λ¨Έκ°€ μ°ΎκΈ° μ–΄λ ΅μŠ΅λ‹ˆλ‹€. μƒμ„±μžμ²˜λŸΌ API μ„€λͺ…에 λͺ…ν™•ν•˜κ²Œ λ“œλŸ¬λ‚˜μ§€ μ•ŠμœΌλ‹ˆ λ¬Έμ„œ 관리λ₯Ό 잘 ν•΄μ•Ό ν•©λ‹ˆλ‹€.

 

 

😎 2. Reference

[λ„μ„œ] Effective Java 3판
[링크, μŠ¬λΌμ΄λ“œμ‰μ–΄] https://www.slideshare.net/lifeinnovator/effective-java-57604973