λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°

πŸ“šμ½μ€ μ±… 정리/μ΄νŽ™ν‹°λΈŒμžλ°”

[μ΄νŽ™ν‹°λΈŒ μžλ°”] 5μž₯ : μ œλ„€λ¦­

μ œλ„€λ¦­ μ§€μ›ν•˜κΈ° μ „ μžλ°”μžλŠ” μ»¬λ ‰μ…˜μ—μ„œ 객체λ₯Ό κΊΌλ‚Ό λ•Œλ§ˆλ‹€ ν˜•λ³€ν™˜μ„ ν•΄μ•Όν–ˆμŒ (μ΄λŠ” μ‹€μˆ˜λ‘œ μΈν•œ λŸ°νƒ€μž„μ—λŸ¬λ₯Ό λ°œμƒμ‹œν‚΄)

κ·Έλž˜μ„œ μ»΄νŒŒμΌλŸ¬λŠ” μ•Œμ•„μ„œ ν˜•λ³€ν™˜ μ½”λ“œλ₯Ό μΆ”κ°€ν•  수 있고 μ—‰λš±ν•œ νƒ€μž…μ˜ 객체λ₯Ό λ„£μœΌλ €λŠ” μ‹œλ„λ₯Ό 컴파일 κ³Όμ •μ—μ„œ μ°¨λ‹¨ν•˜μ—¬ 더 μ•ˆμ „ν•˜κ³  λͺ…ν™•ν•œ ν”„λ‘œκ·Έλž¨μ„ λ§Œλ“€μ–΄μ€€λ‹€.

μ œλ„€λ¦­μ˜ 이점을 μ΅œλŒ€ν•œ 살리고 단점을 μ΅œμ†Œν™”ν•˜μ—¬ μ‚¬μš©ν•΄λ³΄μž.

μ•„μ΄ν…œ 26 : 둜(raw) νƒ€μž…μ€ μ‚¬μš©ν•˜μ§€ 마라

클래슀, μΈν„°νŽ˜μ΄μŠ€ 선언에 ‘νƒ€μž… λ§€κ°œλ³€μˆ˜'κ°€ 쓰이면 μ œλ„€λ¦­ 클래슀, μΈν„°νŽ˜μ΄μŠ€λΌκ³  뢀름

→ 이λ₯Ό 톡틀어 ‘μ œλ„ˆλ¦­ νƒ€μž…'이라고 함

→ ‘μ œλ„€λ¦­ νƒ€μž…’은 λ§€κ°œλ³€μˆ˜ν™” νƒ€μž…μ„ μ •μ˜ν•œλ‹€.

→ ‘μ œλ„€λ¦­ νƒ€μž…'을 μ •μ˜ν•˜λ©΄ ‘raw νƒ€μž…' 도 μ •μ˜λœλ‹€. (νƒ€μž… λ§€κ°œλ³€μˆ˜λ₯Ό μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” νƒ€μž…) ex) List<E> → List (μ œλ„€λ¦­ λ„λž˜ μ „ μ½”λ“œμ™€ ν˜Έν™˜μ„ μœ„ν•΄ 쑴재)

λ²”μš©μ μΈ μ½”λ“œλ₯Ό λ§Œλ“€κΈ° μœ„ν•΄ μ—¬λŸ¬ νƒ€μž…μ„ ν—ˆμš©ν•˜κ³  μ‚¬μš©ν•  λ•Œ μΊμŠ€νŒ…ν•˜λŠ” 방법은 컴파일 νƒ€μž„μ—λŠ” 였λ₯˜κ°€ λ‚˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— 쒋은 방법이 μ•„λ‹ˆλ‹€.

  • λŸ°νƒ€μž„μ—μ„œμ•Ό 였λ₯˜κ°€ λ°œμƒ
  • 였λ₯˜ μ›μΈμ˜ μœ„μΉ˜μ™€ λŸ°νƒ€μž„ μ‹œ 였λ₯˜ λ°œμƒ μœ„μΉ˜κ°€ 멀리 λ–¨μ–΄μ Έ μžˆλ‹€. (전체 μ½”λ“œμ—μ„œ 였λ₯˜λ₯Ό μ°Ύμ•„μ•Όν•  μˆ˜λ„ μžˆλ‹€)

였λ₯˜λŠ” κ°€λŠ₯ν•œ ν•œ μ»΄νŒŒμΌν•  λ•Œ λ°œκ²¬ν•˜λŠ” 것이 κ°€μž₯ μ’‹λ‹€!

μ œλ„€λ¦­μ„ ν™œμš©ν•˜λ©΄ νƒ€μž… 정보가 μ„ μ–Έ μžμ²΄μ— λ…Ήμ•„λ“€κ²Œ λœλ‹€.

private final Collections<Stamp> stamps = ...;

μœ„μ²˜λŸΌ νƒ€μž… 정보λ₯Ό λͺ…μ‹œν•˜λ©΄ Stamp의 μΈμŠ€ν„΄μŠ€λ§Œ λ„£μ–΄μ•Ό μ»΄νŒŒμΌλŸ¬κ°€ μΈμ§€ν•˜κ²Œ λœλ‹€. μ•„λ‹ˆλΌλ©΄ 컴파일 였λ₯˜λ°œμƒ. (μ»΄νŒŒμΌλŸ¬κ°€ μ»¬λ ‰μ…˜μ—μ„œ μ›μ†Œλ₯Ό κΊΌλ‚΄λŠ” λͺ¨λ“  κ³³μ—μ„œ 보이지 μ•ŠλŠ” λͺ…μ‹œλœ νƒ€μž…μœΌλ‘œμ˜ ν˜•λ³€ν™˜μ„ μΆ”κ°€ν•œλ‹€)

raw의 νƒ€μž…μ„ μ“°λ©΄ μ•ˆλœλ‹€

μ œλ„€λ¦­μ΄ μ£ΌλŠ” μ•ˆμ •μ„±κ³Ό ν‘œν˜„λ ₯을 λͺ¨λ‘ μžƒκ²Œ λœλ‹€. 둜 νƒ€μž…μ€ 단지 ν˜Έν™˜μ„± λ•Œλ¬Έμ— λ§Œλ“€μ–΄ λ‘” 것이닀. (μ§€κΈˆκΉŒμ§€ μŒ“μ΄ λ‘œνƒ€μž…μ½”λ“œλ“€μ„ μœ„ν•œ...)

<?> λΉ„ν•œμ •μ  μ™€μΌλ“œμΉ΄λ“œ

μ‹€μ œ νƒ€μž… λ§€κ°œλ³€μˆ˜κ°€ 신경쓰지 μ•Šκ³  μ œλ„€λ¦­ μ‚¬μš© 싢을 λ•Œ

μ˜ˆμ™Έ

클래슀 λ¦¬ν„°λŸ΄μ€ λ‘œνƒ€μž…μ„ μ¨μ•Όν•œλ‹€. λ§€κ°œλ³€μˆ˜ν™” νƒ€μž… κΈˆμ§€

ex) List.class, String[].class, List<?>.classe

둜 νƒ€μž…μ„ μ‚¬μš©ν•˜λ©΄ λŸ°νƒ€μž„μ— μ˜ˆμ™Έκ°€ λ°œμƒν•  수 있고 μ œλ„€λ¦­ νƒ€μž…μ‹œμŠ€ν…œμ΄ μ•„λ‹ˆκ³  μ•ˆμ „ν•˜μ§€ μ•Šλ‹€.

μ•„μ΄ν…œ 27 : 비검사 κ²½κ³ λ₯Ό μ œκ±°ν•˜λΌ

비검사 κ²½κ³ λŠ” λŸ°νƒ€μž„μ— μ˜ˆμ™Έλ₯Ό λ°œμƒμ‹œν‚¬ 수 μžˆλŠ” κ°€λŠ₯성을 λ§ν•œλ‹€.

이 μ˜ˆμ™Έκ°€ λ°œμƒν•˜μ§€ μ•Šλ„λ‘ μ΅œλŒ€ν•œ μ œκ±°ν•˜κ³  제거 μ‹œν‚¬ 방법이 μ—†λ‹€λ©΄ @SuppressWarning("unchecked") λ₯Ό 톡해 κ²½κ³ λ₯Ό μˆ¨κΈ΄λ‹€.

이후 κ²½κ³ λ₯Ό λ¬΄μ‹œν•΄λ„ λ˜λŠ” 이유λ₯Ό 주석을 남겨야 ν•œλ‹€.

μ•„μ΄ν…œ 28 : λ°°μ—΄λ³΄λ‹€λŠ” 리슀트λ₯Ό μ‚¬μš©ν•˜λΌ

  • 배열은 곡변이닀. (ν•˜μœ„νƒ€μž…[]이 μƒμœ„ νƒ€μž…[] κ°€λŠ₯)
    • λŸ°νƒ€μž„μ— μ‹€νŒ¨
// λŸ°νƒ€μž„μ— μ‹€νŒ¨
Obejct[] objectArray = new Long[1];
objectArray[0] = "νƒ€μž…μ΄ λ‹€λ₯΄λ‹€"; // ArrayStoreException
  • List<ν•˜μœ„νƒ€μž…>κ³Ό List<μƒμœ„νƒ€μž…> μ„œλ‘œ ν•˜μœ„/μƒμœ„ νƒ€μž…μ΄ μ•„λ‹˜ (μ œλ„€λ¦­)
    • 컴파일 νƒ€μž„μ— μ‹€νŒ¨
// μ»΄νŒŒμΌνƒ€μž„μ— μ‹€νŒ¨
List<Object> ol = new ArrayList<Long>(); // ν˜Έν™˜λ˜μ§€ μ•ŠλŠ” νƒ€μž…. 컴파일 μ—λŸ¬
ol.add("νƒ€μž…μ΄ λ‹€λ₯΄λ‹€");

μ œλ„€λ¦­μ„ 배열에 μ‚¬μš©ν•˜λ €λ©΄ 비검사 ν˜•λ³€ν™˜μ„ μ œκ±°ν•΄μ•Όν•  수 도 있고 ν˜•λ³€ν™˜ μ˜ˆμ™Έλ„ κ²ͺ을 수 μžˆλ‹€.

λ°°μ—΄λ³΄λ‹€λŠ” 리슀트λ₯Ό μ‚¬μš©ν•˜λ©΄ 였λ₯˜λ‚˜ 경고없이 컴파일 ν•  수 μžˆλ‹€.

μ•„μ΄ν…œ 29 : 이왕이면 μ œλ„€λ¦­ νƒ€μž…μœΌλ‘œ λ§Œλ“€λΌ

μ œλ„€λ¦­ νƒ€μž…μ„ λ§Œλ“œλŠ” 것은 쑰금 λ³΅μž‘ν•˜λ‹€.

ν•˜μ§€λ§Œ ν΄λΌμ΄μ–ΈνŠΈμ—μ„œ 직접 ν˜•λ³€ν™˜ν•˜λŠ” 것보닀 μ œλ„€λ¦­ νƒ€μž…μ΄ 더 μ•ˆμ „ν•˜κ³  μ“°κΈ° νŽΈν•˜λ‹€. (직접 ν˜•λ³€ν™˜ ν•„μš” 없어짐)

μ œλ„€λ¦­μ„ μ‚¬μš©ν•˜λ©΄ κΈ°μ‘΄ ν΄λΌμ΄μ–ΈνŠΈμ— 영ν–₯을 주지 μ•ŠμœΌλ©΄μ„œ μ‚¬μš©ν•  수 μžˆλ‹€.

μ•„μ΄ν…œ 30 : 이왕이면 μ œλ„€λ¦­ λ©”μ„œλ“œλ‘œ λ§Œλ“€λΌ

μ œλ„€λ¦­ λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜λ©΄ 경고없이 컴파일되며, νƒ€μž… μ•ˆμ „ν•˜κ³ , μ“°κΈ° 쉽닀.

직접 ν˜•λ³€ν™˜ν•˜μ§€ μ•Šμ•„λ„ 컴파일 λœλ‹€.

public static <E> Set<E> union(Set<E> s1, Set<E> s2) {
  	Set<E> result = new HashSet<>(s1);
  	result.addAll(s2);
  	return result;
}

μ•„μ΄ν…œ 31 : ν•œμ •μ  μ™€μΌλ“œμΉ΄λ“œλ₯Ό μ‚¬μš©ν•΄ API μœ μ—°μ„±μ„ 높이라

‘λ§€κ°œλ³€μˆ˜ν™” νƒ€μž…’은 λΆˆκ³΅λ³€μ΄λ‹€. 즉, List<ν•˜μœ„νƒ€μž…>κ³Ό List<μƒμœ„νƒ€μž…>λŠ” μ„œλ‘œ ν•˜μœ„/μƒμœ„ νƒ€μž…μ΄ μ•„λ‹ˆλ‹€.

ν•œμ •μ  μ™€μΌλ“œμΉ΄λ“œλ₯Ό μ‚¬μš©ν•˜μ§€ μ•Šκ³  κ·Έλƒ₯ λ§€κ°œλ³€μˆ˜ν™” νƒ€μž…μ„ μ‚¬μš©ν•˜λ©΄ μ„œλ‘œ λΆˆκ³΅λ³€μ΄κΈ° λ•Œλ¬Έμ— λ§žμ§€μ•ŠλŠ” νƒ€μž…μ΄λΌκ³  μ—λŸ¬κ°€ λ°œμƒν•œλ‹€.

ν•˜μ§€λ§Œ μ•„λž˜ μ½”λ“œμ²˜λŸΌ ‘ν•œμ •μ  μ™€μΌλ“œμΉ΄λ“œ'λ₯Ό μ‚¬μš©ν•˜λ©΄ “E의 ν•˜μœ„ λ˜λŠ” μƒμœ„νƒ€μž…μΈ 것듀을 ν¬ν•¨ν•œλ‹€”μ—¬μ„œ μœ μ—°μ„±μ΄ κ·ΉλŒ€ν™” λœλ‹€.

public void pushAll(Iterable<? extends E> src) { // producer : src
  	for (E e : src)
      	push(e);
}

public void popAll(Collection<? super E> dst) { // consumer : dst
  	while (!isEmpty())
      	dst.add(pop());
}

μ•„μ΄ν…œ 32: μ œλ„€λ¦­κ³Ό κ°€λ³€μΈμˆ˜λ₯Ό ν•¨κ»˜ μ“Έ λ•ŒλŠ” μ‹ μ€‘ν•˜μž

κ°€λ³€μΈμˆ˜λŠ” λ©”μ„œλ“œμ— λ„˜κΈ°λŠ” 인수의 개수λ₯Ό ν΄λΌμ΄μ–ΈνŠΈκ°€ μ‘°μ ˆν•  수 있게 ν•˜λŠ” κΈ°λŠ₯이닀.

κ°€λ³€μΈμˆ˜ λ©”μ„œλ“œ 호좜 → κ°€λ³€μΈμˆ˜λ₯Ό λ‹΄λŠ” λ°°μ—΄ 생성

κ°€λ³€μΈμˆ˜λŠ” 배열을 λ‚΄λΆ€λ‘œ 감좔지 λͺ»ν•˜κ³  λ…ΈμΆœν•˜κΈ° λ•Œλ¬Έμ— 좔상화가 μ™„λ²½ν•˜μ§€ λͺ»ν•˜λ‹€.

νƒ€μž… μ•ˆμ „ν•˜μ§€ μ•Šμ§€λ§Œ ν—ˆμš©λœλ‹€.

μ œλ„€λ¦­μ— κ°€λ³€μΈμˆ˜λ₯Ό μ‚¬μš©ν•œλ‹€λ©΄ λ©”μ„œλ“œκ°€ νƒ€μž… μ•ˆμ „ν•˜μ§€ 항상 ν™•μΈν•˜λ„λ‘ μ‘°μ‹¬ν•΄μ„œ μ‚¬μš©ν•˜μž.

μ•„μ΄ν…œ 33 : νƒ€μž… μ•ˆμ „ 이쒅 μ»¨ν…Œμ΄λ„ˆλ₯Ό κ³ λ €ν•˜λΌ

일반적인 μ œλ„€λ¦­ ν˜•νƒœμ—μ„œλŠ” ν•œ μ»¨ν…Œμ΄λ„ˆκ°€ λ‹€λ£° 수 μžˆλŠ” νƒ€μž… λ§€κ°œλ³€μˆ˜μ˜ μˆ˜κ°€ κ³ μ •λ˜μ–΄ μžˆλ‹€. ex) Map<K, V>, List<K> λ“±..

μ»¨ν…Œμ΄λ„ˆ μžμ²΄κ°€ μ•„λ‹Œ ν‚€λ₯Ό ‘νƒ€μž… λ§€κ°œλ³€μˆ˜λ‘œ' λ°”κΎΈλ©΄ μ œμ•½μ—†λŠ” ‘νƒ€μž… μ•ˆμ „ 이쒅 μ»¨ν…Œμ΄λ„ˆ'λ₯Ό λ§Œλ“€ 수 μžˆλ‹€.

Classλ₯Ό ν‚€λ‘œ μ“°λ©° 이λ₯Ό νƒ€μž…ν† ν°μ΄λΌ ν•œλ‹€.

 

-ν΄λΌμ΄μ–ΈνŠΈ μ½”λ“œ-

// μ½”λ“œ 33-2 νƒ€μž… μ•ˆμ „ 이쒅 μ»¨ν…Œμ΄λ„ˆ νŒ¨ν„΄ - ν΄λΌμ΄μ–ΈνŠΈ (199μͺ½)
    public static void main(String[] args) {
        Favorites f = new Favorites();
        
        f.putFavorite(String.class, "Java");
        f.putFavorite(Integer.class, 0xcafebabe);
        f.putFavorite(Class.class, Favorites.class);
       
        String favoriteString = f.getFavorite(String.class);
        int favoriteInteger = f.getFavorite(Integer.class);
        Class<?> favoriteClass = f.getFavorite(Class.class);
        
        System.out.printf("%s %x %s%n", favoriteString,
                favoriteInteger, favoriteClass.getName());
    }

-Favoriteμ½”λ“œ-

public class Favorites {
  	private Map<Class<?>, Object> favorites = new HashMap<>();
  	
  	public <T> void putFavorite(Class<T> type, T instance) {
      	favorites.put(Object.requireNonNull(type), instance);
    }
  
  	public <T> getFavorite(Class<T> type) {
      	return type.cast(favorite.get(type));
    }
}

맡이 μ•„λ‹Œ ν‚€κ°€ μ™€μΌλ“œ νƒ€μž…μ΄κΈ° λ•Œλ¬Έμ— λͺ¨λ“  ν‚€κ°€ μ„œλ‘œ λ‹€λ₯Έ λ§€κ°œλ³€μˆ˜ν™” νƒ€μž…μΌ 수 μžˆλ‹€λŠ” λœ»μ΄λ‹€.

λ”°λΌμ„œ, Class<String>이든 Class<Integer>λ“  λͺ¨λ‘ κ°€λŠ₯ν•˜λ‹€. (λ‹€μ–‘ν•œ νƒ€μž…μ§€μ›)

 

Map의 κ°’ νƒ€μž…μ€ λ‹¨μˆœνžˆ Object이닀. μ΄λŠ” 킀와 κ°’μ‚¬μ΄μ˜ νƒ€μž…κ΄€κ³„λ₯Ό λ³΄μ¦ν•˜μ§€ μ•ŠλŠ”λ‹€λŠ” 것이닀.

ν•˜μ§€λ§Œ μš°λ¦¬λŠ” 값을 κΊΌλ‚Ό λ•Œ ν‚€λ₯Ό λ„˜κ²¨ λ°›μ•„μ„œ 그둜 μΊμŠ€νŒ…ν•˜μ—¬ 동적 ν˜•λ³€ν™˜ν•  수 μžˆλ‹€.