item 6 Jung inchul - JAVA-JIKIMI/EFFECTIVE-JAVA3 GitHub Wiki

Effective Java 3e μ•„μ΄ν…œ 6λ₯Ό μš”μ•½ν•œ λ‚΄μš© μž…λ‹ˆλ‹€.

λ˜‘κ°™μ€ κΈ°λŠ₯의 객체λ₯Ό 맀번 μƒμ„±ν•˜κΈ°λ³΄λ‹€λŠ” 객체 ν•˜λ‚˜λ₯Ό μž¬μ‚¬μš©ν•˜λŠ” 편이 λ‚˜μ„ λ•Œκ°€ λ§Žλ‹€. 특히 λΆˆλ³€ κ°μ²΄λŠ” μ–Έμ œλ“  μž¬μ‚¬μš©ν•  수 μžˆλ‹€.

String s = new String("bikini");

μœ„ μ½”λ“œλŠ” 싀행될 λ•Œλ§ˆλ‹€ String μΈμŠ€ν„΄μŠ€λ₯Ό μƒˆλ‘œ λ§Œλ“ λ‹€.

String s = "bikini";

이 μ½”λ“œλŠ” μƒˆλ‘œμš΄ μΈμŠ€ν„΄μŠ€λ₯Ό 맀번 λ§Œλ“œλŠ” λŒ€μ‹  ν•˜λ‚˜μ˜ String μΈμŠ€ν„΄μŠ€λ₯Ό μ‚¬μš©ν•œλ‹€. λ‚˜μ•„κ°€ 이 방식을 μ‚¬μš©ν•œλ‹€λ©΄ 같은 가상 λ¨Έμ‹  μ•ˆμ—μ„œ 이와 λ˜‘κ°™μ€ λ¬Έμžμ—΄ λ¦¬ν„°λŸ΄μ„ μ‚¬μš©ν•˜λŠ” λͺ¨λ“  μ½”λ“œκ°€ 같은 객체λ₯Ό μž¬μ‚¬μš©ν•¨μ΄ 보μž₯λœλ‹€.

μƒμ„±μž λŒ€μ‹  정적 νŒ©ν„°λ¦¬ λ©”μ„œλ“œλ₯Ό μ œκ³΅ν•˜λŠ” λΆˆλ³€ ν΄λž˜μŠ€μ—μ„œλŠ” 정적 νŒ©ν„°λ¦¬ λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•΄ λΆˆν•„μš”ν•œ 객체 생성을 ν”Όν•  수 μžˆλ‹€.

μƒμ„±μžλŠ” ν˜ΈμΆœν•  λ•Œλ§ˆλ‹€ μƒˆλ‘œμš΄ 객체λ₯Ό λ§Œλ“€μ§€λ§Œ νŒ©ν„°λ¦¬ λ©”μ„œλ“œλŠ” μ „ν˜€ 그렇지 μ•Šλ‹€.

생성 λΉ„μš©μ΄ μ•„μ£Ό λΉ„μ‹Ό 객체도 λ”λŸ¬ μžˆλ‹€. 이런 'λΉ„μ‹Ό 객체'κ°€ λ°˜λ³΅ν•΄μ„œ ν•„μš”ν•˜λ‹€λ©΄ μΊμ‹±ν•˜μ—¬ μž¬μ‚¬μš©ν•˜κΈΈ κΆŒν•œλ‹€.

static boolean isRomanNumeral(String s) {
	return s.marches("^(?=.)M*(C[MD] }D?C{0,3})"
					+ "(X[CL]}L?X{0,3})(I[XV]|V?I{0,3})$");

String.matchesλŠ” μ •κ·œν‘œν˜„μ‹μœΌλ‘œ λ¬Έμžμ—΄ ν˜•νƒœλ₯Ό ν™•μΈν•˜λŠ” κ°€μž₯ μ‰¬μš΄ λ°©λ²•μ΄μ§€λ§Œ, μ„±λŠ₯이 μ€‘μš”ν•œ μƒν™©μ—μ„œ λ°˜λ³΅ν•΄ μ‚¬μš©ν•˜κΈ°μ—” μ ν•©ν•˜μ§€ μ•Šλ‹€. 이 λ©”μ„œλ“œκ°€ λ‚΄λΆ€μ—μ„œ λ§Œλ“œλŠ” μ •κ·œν‘œν˜„μ‹μš© Pattern μΈμŠ€ν„΄μŠ€λŠ” ν•œ 번 μ“°κ³  λ²„λ €μ Έμ„œ κ³§λ°”λ‘œ 가비지 μ»¬λ ‰μ…˜ λŒ€μƒμ΄ λœλ‹€.

μ„±λŠ₯을 κ°œμ„ ν•˜λ €λ©΄ ν•„μš”ν•œ μ •κ·œν‘œν˜„μ‹μ„ ν‘œν˜„ν•˜λŠ” (λΆˆλ³€μΈ)Pattern μΈμŠ€ν„΄μŠ€λ₯Ό 클래슀 μ΄ˆκΈ°ν™”(정적 포기화) κ³Όμ •μ—μ„œ 직접 생성해 캐싱해두고, λ‚˜μ€‘μ— isRomanNumral λ©”μ„œλ“œκ°€ 호좜될 λ•Œλ§ˆλ‹€ 이 μΈμŠ€ν„΄μŠ€λ₯Ό μž¬μ‚¬μš©ν•œλ‹€.

κ°œμ„  μ „μ—μ„œλŠ” 쑴재쑰차 λͺ°λžλ˜ Pattern μΈμŠ€ν„΄μŠ€λ₯Ό static final ν•„λ“œλ‘œ 끄집어내고 이름을 지어주어 μ½”λ“œμ˜ μ˜λ―Έκ°€ 훨씬 잘 λ“œλŸ¬λ‚œλ‹€.

지연 μ΄ˆκΈ°ν™”λŠ” μ½”λ“œλ₯Ό λ³΅μž‘ν•˜κ²Œ λ§Œλ“œλŠ”λ°, μ„±λŠ₯은 크게 κ°œμ„ λ˜μ§€ μ•Šμ„ λ•Œκ°€ 많기 λ•Œλ¬Έμ΄λ‹€.

Q1. 지연 μ΄ˆκΈ°ν™”λž€?
μ΄ˆκΈ°ν™” 지연(Lazy initialization)은 ν•„λ“œ μ΄ˆκΈ°ν™”λ₯Ό μ‹€μ œλ‘œ κ·Έ 값이 쓰일 λ•ŒκΉŒμ§€ λ―Έλ£¨λŠ” 것이닀. 값을 μ‚¬μš©ν•˜λŠ” 곳이 μ—†λ‹€λ©΄ ν•„λ“œλŠ” κ²°μ½” μ΄ˆκΈ°ν™”λ˜μ§€ μ•Šμ„ 것이닀.

객체가 λΆˆλ³€μ΄λΌλ©΄ μž¬μ‚¬μš©ν•΄λ„ μ•ˆμ „ν•¨μ΄ λͺ…λ°±ν•˜λ‹€. ν•˜μ§€λ§Œ 훨씬 덜 λͺ…ν™•ν•˜κ±°λ‚˜ 심지어 직관에 λ°˜λŒ€λ˜λŠ” 상황도 μžˆλ‹€.

κ·Έλ ‡λ‹€λ©΄ μ–΄λŒ‘ν„°λ₯Ό μƒκ°ν•΄λ³΄μž. μ–΄λŒ‘ν„°λŠ” μ‹€μ œ μž‘μ—…μ€ 뒷단 객체에 μœ„μž„ν•˜κ³ , μžμ‹ μ€ 제2의 μΈν„°νŽ˜μ΄μŠ€ 역할을 ν•΄μ£ΌλŠ” 객체이닀.

μ˜ˆμ»¨ν…Œ Map μΈν„°νŽ˜μ΄μŠ€μ˜ KeySet λ©”μ„œλ“œλŠ” Map 객체 μ•ˆμ˜ ν‚€ μ „λΆ€λ₯Ό 담은 Set λ·°λ₯Ό λ°˜ν™˜ν•œλ‹€. KeySet을 ν˜ΈμΆœν•  λ•Œλ§ˆλ‹€ μƒˆλ‘œμš΄ Set μΈμŠ€ν„΄μŠ€κ°€ λ§Œλ“€μ–΄λ¦¬λΌκ³  μˆœμ§„ν•˜κ²Œ 생각할 μˆ˜λ„ μžˆμ§€λ§Œ, 사싀은 맀번 같은 Set μΈμŠ€ν„΄μŠ€λ₯Ό λ°˜ν™˜ν• μ§€λ„ λͺ¨λ₯Έλ‹€.

Q1. KeySet에 λŒ€ν•œ μ˜ˆμ œκ°€ ν•„μš”ν•˜λ‹€.

λΆˆν•„μš”ν•œ 객체λ₯Ό λ§Œλ“€μ–΄λ‚΄λŠ” 또 λ‹€λ₯Έ 예둜 μ˜€ν† λ°•μ‹±μ„ λ“€ 수 μžˆλ‹€.

μ˜€ν† λ°•μ‹±μ€ κΈ°λ³Έ νƒ€μž…κ³Ό 그에 λŒ€μ‘ν•˜λŠ” λ°•μ‹±λœ κΈ°λ³Έ νƒ€μž…μ˜ ꡬ뢄을 νλ €μ£Όμ§€λ§Œ, μ™„μ „νžˆ μ—†μ• μ£ΌλŠ” 것은 μ•„λ‹ˆλ‹€

private static long sum() {
	Long sum = 0L;
	for( long i = 0; i <= Integer.MAX_VALUE; i++ )
		sum += i;

	return sum;
}

sum λ³€μˆ˜λ₯Ό long이 μ•„λ‹Œ Long으둜 μ„ μ–Έν•΄μ„œ λΆˆν•„μš”ν•œ Long μΈμŠ€ν„΄μŠ€κ°€ μ•½ 231κ°œλ‚˜ λ§Œλ“€μ–΄μ§„ 것이닀.

κ΅ν›ˆμ€ λͺ…ν™•ν•˜λ‹€. λ°•μ‹±λœ κΈ°λ³Έ νƒ€μž…λ³΄λ‹€λŠ” κΈ°λ³Έ νƒ€μž…μ„ μ‚¬μš©ν•˜κ³  μ˜λ„μΉ˜ μ•Šμ€ μ˜€ν† λ°•μ‹±μ΄ μˆ¨μ–΄λ“€μ§€ μ•Šλ„λ‘ μ£Όμ˜ν•˜μž.

거꾸둜 μ•„μ£Ό 무거운 객체가 μ•„λ‹Œ λ‹€μŒμ—μ•Ό λ‹¨μˆœνžˆ 객체 생성을 ν”Όν•˜κ³ μž μ—¬λŸ¬λΆ„λ§Œμ˜ 객체 풀을 λ§Œλ“€μ§€λŠ” 말자

ν•˜μ§€λ§Œ μΌλ°˜μ μœΌλ‘œλŠ” 자체 객체 풀은 μ½”λ“œλ₯Ό ν—·κ°ˆλ¦¬κ²Œ λ§Œλ“€κ³  λ©”λͺ¨λ¦¬ μ‚¬μš©λŸ‰μ„ 늘리고 μ„±λŠ₯을 λ–¨μ–΄λœ¨λ¦°λ‹€.

이번 μ•„μ΄ν…œμ΄ "κΈ°μ‘΄ 객체λ₯Ό μž¬μ‚¬μš©ν•΄μ•Ό ν•œλ‹€λ©΄ μƒˆλ‘œμš΄ 객체λ₯Ό λ§Œλ“€μ§€ 마라'라면 μ•„μ΄ν…œ 50은 "μƒˆλ‘œμš΄ 객체λ₯Ό λ§Œλ“€μ–΄μ•Ό ν•œλ‹€λ©΄ κΈ°μ‘΄ 객체λ₯Ό μž¬μ‚¬μš©ν•˜μ§€ 마라"

방어적 볡사에 μ‹€νŒ¨ν•˜λ©΄ μ–Έμ œ ν„°μ Έ λ‚˜μ˜¬μ§€ λͺ¨λ₯΄λŠ” 버그와 λ³΄μ•ˆ ꡬ멍으둜 μ΄μ–΄μ§€μ§€λ§Œ, λΆˆν•„μš”ν•œ 객체 생성은 κ·Έμ € μ½”λ“œ ν˜•νƒœμ™€ μ„±λŠ₯μ—λ§Œ 영ν–₯을 μ€€λ‹€.

⚠️ **GitHub.com Fallback** ⚠️