item 49 hyowon - JAVA-JIKIMI/EFFECTIVE-JAVA3 GitHub Wiki

8μž₯ λ©”μ„œλ“œ

이번 μž₯μ—μ„œλŠ” λ©”μ„œλ“œ μ„€κ³„μ‹œ μ£Όμ˜ν•  점을 μ‚΄νŽ΄λ³Ό 것이닀. 더 κ΅¬μ²΄μ μœΌλ‘œλŠ” μ‚¬μš©μ„±, 견고성, μœ μ—°μ„±μ„ λ‹¬μ„±ν•˜κΈ° μœ„ν•΄ λ§€κ°œλ³€μˆ˜μ™€ λ°˜ν™˜κ°’μ˜ 처리, λ©”μ„œλ“œ μ‹œκ·Έλ‹ˆμ²˜μ˜ 섀계, λ¬Έμ„œν™” 방법 등을 닀룬닀. 8μž₯의 λ‚΄μš© 쀑 상당 뢀뢄은 μƒμ„±μžμ—λ„ μ μš©λ€λ‹€.

[item 49] λ§€κ°œλ³€μˆ˜κ°€ μœ νš¨ν•œμ§€ κ²€μ‚¬ν•˜λΌ

이번 itemμ—λŠ” λ©”μ„œλ“œ λ§€κ°œλ³€μˆ˜μ˜ μ²˜λ¦¬λ°©λ²•μ„ 닀룬닀.

λ©”μ„œλ“œλŠ” μ΅œλŒ€ν•œ λ²”μš©μ μœΌλ‘œ 섀계해야 ν•˜μ§€λ§Œ, κ΅¬ν˜„ν•˜λ €λŠ” κ°œλ… μžμ²΄κ°€ λ§€κ°œλ³€μˆ˜μ— μ œμ•½μ„ λ‚΄μž¬ν•œ κ²½μš°λ„ λ“œλ¬Όμ§€ μ•Šλ‹€.

예λ₯Ό λ“€λ©΄, 인덱슀 값은 음수이면 μ•ˆλ˜κ³ , 객체 μ°Έμ‘°λŠ” null이 μ•„λ‹ˆμ–΄μ•Ό ν•œλ‹€λŠ” 식이닀. 이런 μ œμ•½μ€ λ°˜λ“œμ‹œ λ¬Έμ„œν™”ν•΄μ•Ό ν•˜λ©°, λ©”μ„œλ“œ λͺΈμ²΄κ°€ μ‹œμž‘λ˜κΈ° 전에 검사해야 ν•œλ‹€.

μ΄λŠ” 였λ₯˜λŠ” κ°€λŠ₯ν•œ 빨리 μž‘μ•„μ•Ό ν•œλ‹€λŠ” 일반 원칙과도 λ§žλ‹Ώμ•„μžˆλŠ” λ‚΄μš©μœΌλ‘œ, 였λ₯˜λ₯Ό λ°œμƒν•œ μ¦‰μ‹œ μž‘μ§€ λͺ»ν•˜λ©΄ ν•΄λ‹Ή 였λ₯˜λ₯Ό κ°μ§€ν•˜κΈ° μ–΄λ €μ›Œμ§€κ³ , κ°μ§€ν•˜λ”λΌλ„ 였λ₯˜μ˜ λ°œμƒ 지점을 μ°ΎκΈ° μ–΄λ €μ›Œμ§„λ‹€.

λ§€κ°œλ³€μˆ˜ μœ νš¨μ„± 검사λ₯Ό μ œλŒ€λ‘œ ν•˜μ§€ λͺ»ν•˜λ©΄

μ‹€νŒ¨ μ›μžμ„±(failure atomicity)을 μ–΄κΈΈ 수 μžˆλ‹€.

  • λ©”μ„œλ“œκ°€ μˆ˜ν–‰λ˜λŠ” 쀑간에 λͺ¨ν˜Έν•œ μ˜ˆμ™Έλ₯Ό λ˜μ§€λ©° μ‹€νŒ¨ν•  수 μžˆλ‹€.
  • (더 λ‚˜μœ 상황) λ©”μ„œλ“œκ°€ 잘 μˆ˜ν–‰λ˜μ§€λ§Œ 잘λͺ»λœ κ²°κ³Όλ₯Ό λ°˜ν™˜ν•  수 μžˆλ‹€.
  • (λ”μš± λ‚˜μœ 상황) λ©”μ„œλ“œλŠ” λ¬Έμ œμ—†μ΄ μˆ˜ν–‰λμ§€λ§Œ μ–΄λ–€ 객체λ₯Ό μ΄μƒν•œ μƒνƒœλ‘œ λ§Œλ“€μ–΄μ„œ 미래 μ•Œ 수 μ—†λŠ” μ‹œμ μ— 이 λ©”μ„œλ“œμ™€ κ΄€λ ¨μ—†λŠ” 였λ₯˜λ₯Ό λ‚Έλ‹€.

public, protected λ©”μ„œλ“œλŠ” λ§€κ°œλ³€μˆ˜ 값이 잘λͺ»λμ„ λ•Œ λ˜μ§€λŠ” μ˜ˆμ™Έλ₯Ό λ¬Έμ„œν™”ν•΄μ•Ό ν•œλ‹€. @throws μžλ°”λ… νƒœκ·Έλ₯Ό μ‚¬μš©ν•˜κ³ , μ˜ˆμ™Έ μ’…λ₯˜λŠ” 보톡 IllegalArgumentException, IndexOutOfException, NullPointerException 쀑 ν•˜λ‚˜μΌ 것이닀.

μ˜ˆμ™Έλ₯Ό λ¬Έμ„œν™”ν•  λ•Œ μ°Έκ³ ν•  점

  • λ§€κ°œλ³€μˆ˜μ˜ μ œμ•½μ„ λ¬Έμ„œν™”ν–ˆλ‹€λ©΄, 어겼을 λ•Œ λ°œμƒν•˜λŠ” μ˜ˆμ™Έλ„ κΈ°μˆ ν•œλ‹€.
  • 클래슀 μˆ˜μ€€ 주석. λͺ¨λ“  μ˜ˆμ™Έλ₯Ό κΈ°μˆ ν•˜μ§€ μ•Šκ³  ν•΄λ‹Ή 클래슀 μˆ˜μ€€μ— λ§žλŠ” μ˜ˆμ™Έλ₯Ό μ„€λͺ…ν•œλ‹€.
    • ex) BigInteger의 modλ©”μ„œλ“œ λ§€κ°œλ³€μˆ˜κ°€ null이면 NPEλ₯Ό λ˜μ§€μ§€λ§Œ 이에 λŒ€ν•œ λ¬Έμ„œν™”λŠ” ν•˜μ§€ μ•ŠλŠ”λ‹€.

예)

/**
 * (ν˜„μž¬ κ°’ mod m) 값을 λ°˜ν™˜ν•œλ‹€. 이 λ©”μ„œλ“œλŠ”
 * 항상 음이 μ•„λ‹Œ BigIntegerλ₯Ό λ°˜ν™˜ν•œλ‹€λŠ” μ μ—μ„œ remainder λ©”μ„œλ“œμ™€ λ‹€λ₯΄λ‹€.
 * 
 * @param m κ³„μˆ˜(μ–‘μˆ˜μ—¬μ•Ό ν•œλ‹€.)
 * @return ν˜„μž¬ κ°’ mod m
 * @throws ArithmeticException m이 0보닀 μž‘κ±°λ‚˜ κ°™μœΌλ©΄ λ°œμƒν•œλ‹€.
 */
public BigInteger mod(BigInteger m) {
    if (m.signum() <= 0)
        throw new ArithmeticException("κ³„μˆ˜(m)λŠ” μ–‘μˆ˜μ—¬μ•Ό ν•©λ‹ˆλ‹€. " + m);
    ... // 계산 μˆ˜ν–‰
}

λ§€κ°œλ³€μˆ˜ Null Check 방법

  1. (java 7) java.util.Objects.requireNonNull λ©”μ„œλ“œ. μ›ν•˜λŠ” μ˜ˆμ™Έ 메세지 지정이 κ°€λŠ₯ν•˜κ³  μž…λ ₯을 κ·ΈλŒ€λ‘œ λ°˜ν™˜ν•˜λ―€λ‘œ 값을 μ‚¬μš©ν•˜λŠ” λ™μ‹œμ— null 검사λ₯Ό μˆ˜ν–‰ν•  수 μžˆλ‹€.
void test(Map<String,Object> param) {
		// μ˜€λ²„λ‘œλ”©μœΌλ‘œ 3κ°€μ§€λ‘œ κ΅¬ν˜„λΌμ–΄ μžˆλ‹€.
		Objects.requireNonNull(param);
		Objects.requireNonNull(param, "param은 λ„μž…λ‹ˆλ‹€");
		Objects.requireNonNull(param, ()->"param은 λ„μž…λ‹ˆλ‹€.");
}
  1. (java 9) checkFromIndexSize, checkFromToIndex, checkIndex λ©”μ„œλ“œ. μ˜ˆμ™Έ λ©”μ‹œμ§€λ₯Ό 지정할 수 μ—†κ³ , λ¦¬μŠ€νŠΈμ™€ λ°°μ—΄ μ „μš©μœΌλ‘œ 섀계됐닀. λ‹«νžŒ λ²”μœ„λŠ” 닀루지 λͺ»ν•œλ‹€.
int index = 4;
int length = 6;
int size = 2;
int toIndex = 2;

Objects.checkIndex(index, length); // indexλ₯Ό 체크
Objects.checkFromIndexSize(fromIndex,size,length); // fromIndex, fromIndex + size λ₯Ό 체크
Objects.checkFromToIndex(fromIndex,toIndex,length); // fromIndex, toIndex λ₯Ό 체크
  1. public이 μ•„λ‹Œ λ©”μ„œλ“œλΌλ©΄ assertλ₯Ό μ‚¬μš© κ°€λŠ₯.
private static void sort(long a[], int offset, int length) {
	assert a != null;
	assert offset >= 0 && offset <= a.length;
	assert length >= 0 && lenfth <= a.length - offset;
	... // 계산 μˆ˜ν–‰
}

assertκ°€ 일반적 μœ νš¨μ„± 검사와 λ‹€λ₯Έ 점

  • μ‹€νŒ¨ν•˜λ©΄ AssertionError을 λ˜μ§„λ‹€.
  • μ‹€ν–‰μ‹œ νŠΉμ • μ˜΅μ…˜(-ea)을 μ€˜μ•Όλ§Œ μˆ˜ν–‰λ˜κΈ° λ•Œλ¬Έμ— λŸ°νƒ€μž„(μƒμš©)에선 μ•„λ¬΄λŸ° νš¨κ³Όλ„, μ„±λŠ₯ μ €ν•˜λ„ μ—†λ‹€.

μƒμ„±μž

"λ‚˜μ€‘μ— μ“°λ €κ³  μ €μž₯ν•˜λŠ” λ§€κ°œλ³€μˆ˜μ˜ μœ νš¨μ„±μ„ κ²€μ‚¬ν•˜λΌ"λŠ” μ›μΉ™μ˜ νŠΉμˆ˜ν•œ 사둀닀. μƒμ„±μž λ§€κ°œλ³€μˆ˜μ˜ μœ νš¨μ„± κ²€μ‚¬λŠ” 클래슀 λΆˆλ³€μ‹μ„ μ–΄κΈ°λŠ” 객체가 λ§Œλ“€μ–΄μ§€μ§€ μ•Šκ²Œ ν•˜λŠ” 데 κΌ­ ν•„μš”ν•˜λ‹€.

λ§€κ°œλ³€μˆ˜ μœ νš¨μ„±μ„ κ²€μ‚¬ν•˜μ§€ μ•ŠλŠ” 경우

  • μœ νš¨μ„± κ²€μ‚¬λΉ„μš©μ΄ μ§€λ‚˜μΉ˜κ²Œ 높은 경우
  • 계산 κ³Όμ •μ—μ„œ μ•”λ¬΅μ μœΌλ‘œ 검사가 μˆ˜ν–‰λ  경우

예λ₯Ό λ“€μ–΄ Collections.sort(List) 처럴 객체 리슀트λ₯Ό μ •λ ¬ν•˜λŠ” λ©”μ„œλ“œμ˜ 경우, 리슀트 μ•ˆμ˜ 객체듀이 비ꡐ될 수 μžˆμ–΄μ•Ό ν•œλ‹€. 그런데 리슀트의 μ •λ ¬ κ³Όμ •μ—μ„œ 비ꡐ가 μ΄λ€„μ§€λ―€λ‘œ 객체듀이 μƒν˜Έ 비ꡐ κ°€λŠ₯ν•œμ§€ κ²€μ‚¬ν•˜λŠ” 것에 별닀λ₯Έ 싀읡이 μ—†λ‹€. κ·ΈλŸ¬λ‚˜ 암묡적 μœ νš¨μ„±κ²€μ‚¬μ— λ„ˆλ¬΄ μ˜μ‘΄ν–ˆλ‹€κ°€ μ‹€νŒ¨ μ›μžμ„±μ„ ν•΄μΉ  수 μžˆμœΌλ‹ˆ μ£Όμ˜ν•˜μž.

정리

λ©”μ„œλ“œλ‚˜ μƒμ„±μžλ₯Ό μž‘μ„±ν•  λ•Œ λ§€κ°œλ³€μˆ˜μ— μ–΄λ–€ μ œμ•½μ΄ μžˆμ„μ§€ μƒκ°ν•˜μž. κ·Έ μ œμ•½λ“€μ„ λ¬Έμ„œν™”ν•˜κ³  λ©”μ„œλ“œ μ½”λ“œ μ‹œμž‘ λΆ€λΆ„μ—μ„œ λͺ…μ‹œμ μœΌλ‘œ 검사해야 ν•œλ‹€. 였λ₯˜λŠ” κ°€λŠ₯ν•œ 빨리 λ°œμƒν•œ κ³³μ—μ„œ μž‘μ•„μ•Ό ν•œλ‹€.