ch21 : Generic

λͺ©μ°¨

Generic μ‚¬μš©ν•˜λŠ” 이유?

λ§Œμ•½ DTO의 λ©€λ²„ν•„λ“œλ₯Ό Object둜 ν•  경우,

리턴값을 Object둜 λ°›μ•„μ„œ μ‹€μ œ μ‚¬μš©μ‹œμ—λŠ” ν˜•λ³€ν™˜μ„ ν•΄μ£Όμ–΄μ•Όν•œλ‹€.

λ‹€λ§Œ, μ΄λ•Œ μ‹€μ œ μ–΄λ–€ μžλ£Œν˜•μΈμ§€ ν˜Όλ™λ  수 μžˆλ‹€. (instanceofλ₯Ό 톡해 직접 if-else문으둜 νƒ€μž…μ„ 점검해쀄 μˆ˜λ„ μžˆμ§€λ§Œ λ²ˆκ±°λ‘­λ‹€.)

β‡’ μ΄λ•Œ 이 μžλ£Œν˜•μ„ 컴파일 μ‹œμ μ— 점검할 수 μžˆλ„λ‘ ν•΄μ£ΌλŠ” 것이 Generic이닀!

μ˜ˆμ‹œ)

πŸ’‘ 이런 μ‹μœΌλ‘œ ν˜•λ³€ν™˜μ„ 직접 ν•΄μ£Όμ§€ μ•Šκ³ , ν•΄λ‹Ή μžλ£Œν˜•μ΄ κ·ΈλŒ€λ‘œ λ¦¬ν„΄λœλ‹€. μ΄λ•Œ λ§Œμ•½ μžλ£Œν˜•μ΄ λ‹€λ₯΄λ©΄, 컴파일 μ—λŸ¬κ°€ λ°œμƒν•œλ‹€.

μ œλ„€λ¦­ νƒ€μž… 이름 μ •ν•˜κΈ°

  • E : μš”μ†Œ (μžλ°” Collections)

  • K : ν‚€

  • N : 숫자

  • T : νƒ€μž…

  • V : κ°’

  • S, U, V : 각각 2,3,4 번째 μ„ μ–Έλœ νƒ€μž…

Wildcard

  • <?>

  • λ§€κ°œλ³€μˆ˜λ‘œ μ—¬λŸ¬ νƒ€μž…μ„ λ°›κ³  싢을 경우 <?>을 μ‚¬μš©ν•œλ‹€.

    • μ œλ„€λ¦­ 클래슀의 νƒ€μž…λ§Œ λ°”κΎΌλ‹€κ³  μ˜€λ²„λ‘œλ”©ν•  μˆ˜λŠ” 없기에 μ™€μΌλ“œμΉ΄λ“œλ₯Ό μ‚¬μš©ν•¨.

  • 그리고 ν•΄λ‹Ή λ©”μ†Œλ“œ λ‚΄μ—μ„œλŠ” instanceofλ₯Ό ν†΅ν•΄μ„œ νƒ€μž…μ„ ν™•μΈν•˜λ©΄ λœλ‹€.

  • μ˜ˆμ‹œ) λ©”μ†Œλ“œμ—μ„œ λ§€κ°œλ³€μˆ˜λ‘œ ν•œκ°€μ§€ νƒ€μž…λ§Œ 받을 수 μžˆλ„λ‘ λ˜μ–΄μžˆλ‹€.

    // μ œλ„€λ¦­ 클래슀
    public class WildcardGeneric<W> {
      W wildcard;
    
    public void setWildcard(W wildcard) {
        this.wildcard = wildcard;
    	}
    
    public W getWildcard() {
        return wildcard;
    	}
    }
    
    // μ œλ„ˆλ¦­ 객체 생성
    WildcardGeneric<String> tmp = new WildcardGeneric<String>();
    wildcardMethod(tmp); // ν•¨μˆ˜ 호좜
    
    // ν•¨μˆ˜-> λ§€κ°œλ³€μˆ˜ Stringνƒ€μž…λ§Œ 받을 수 있음
    public void wildcardMethod(WildcardGeneric<String> c) {
    	String val = c.getValue();
      // ...
    }
  • 단, <?> μ™€μΌλ“œμΉ΄λ“œλŠ” λ§€κ°œλ³€μˆ˜λ‘œλ§Œ μ‚¬μš©ν•  것! 객체 μ„ μ–Έ μ‹œμ—λ„ μ‚¬μš©ν•  μˆ˜λŠ” μžˆμ§€λ§Œ, νŠΉμ • νƒ€μž…μœΌλ‘œ 값을 ν• λ‹Ήν• μˆ˜λŠ” μ—†λ‹€.

    // λ§€κ°œλ³€μˆ˜λ‘œ μ—¬λŸ¬ νƒ€μž…μ„ 받을 수 있음
    public void wildcardMethod(WildcardGeneric<?> c) {
    	Object val = c.getValue();
    	if(val instanceof String) {
      // 
    	}
    }

Bounded Wildcard

  • <? extends λΆ€λͺ¨ν΄λž˜μŠ€>

  • μ™€μΌλ“œμΉ΄λ“œμ˜ νƒ€μž… λ²”μœ„λ₯Ό μ •ν•  수 μžˆλ‹€.

  • λ§€κ°œλ³€μˆ˜/λ¦¬ν„΄κ°’μ—μ„œ <?> λŒ€μ‹  <? extends λΆ€λͺ¨ν΄λž˜μŠ€> 을 μ‚¬μš©ν•˜λ©΄, 상속받은 λΆ€λͺ¨ν΄λž˜μŠ€λ§Œ 받을 수 μžˆλ‹€.

public void callWildcardMethod(WildcardGeneric<T extends Car> c) {
	Car val = c.getValue();
	//...
}
  • 단, 이 κ²½μš°μ—λŠ” λ§€κ°œλ³€μˆ˜λ‘œ 온 λ³€μˆ˜μ— 값을 μΆ”κ°€ν•  수 μ—†λ‹€.

    • μ™€μΌλ“œμΉ΄λ“œλ‘œ μ„ μ–Έλœ λ³€μˆ˜λŠ” νŠΉμ • νƒ€μž…μœΌλ‘œ 값이 할당될 수 μ—†κΈ° λ•Œλ¬Έ!

    • λ§€κ°œλ³€μˆ˜λ‘œ 온 λ³€μˆ˜μ— 값을 μΆ”κ°€ν•˜κ³  μ‹ΆμœΌλ©΄,

    • λ©”μ†Œλ“œ μ„ μ–Έ μ‹œ 리턴 νƒ€μž… μ•žμ— μ œλ„ˆλ¦­ν•œ νƒ€μž…μ„ μ„ μ–Έν•΄ μ£Όκ³ , κ·Έ νƒ€μž…μ„ 맀개 λ³€μˆ˜μ—μ„œ μ‚¬μš©ν•˜λ©΄ λœλ‹€.

    public<T> void callWildcardMethod(WildcardGeneric<T> c, T addValue) {
      c.setWildcard(addValue);
      T value = c.getWildcard();
      System.out.println(value);
    }

Last updated