πŸ’Š Java & Kotlin & Spring/- Java & kotlin

[Java 심화] Generic(μ œλ„€λ¦­)을 ν•΅μ‹¬λ§Œ μ΄ν•΄ν•΄λ³΄μž.

Wonit 2020. 8. 27. 13:39

이 μ‹œλ¦¬μ¦ˆλŠ” Springμ—μ„œ Generic을 μ΄μš©ν•˜μ—¬ CRUD μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬μ„±ν•΄λ³΄μž.와 μ΄μ–΄μ§€λŠ” κΈ€ μž…λ‹ˆλ‹€.

  1. Generic(μ œλ„ˆλ¦­)을 ν•΅μ‹¬λ§Œ μ΄ν•΄ν•΄λ³΄μž.
  2. Springμ—μ„œ Generic을 μ΄μš©ν•˜μ—¬ CRUD μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬μ„±ν•΄λ³΄μž.

이 글은 이둠에 κ΄€λ ¨ν•œ 글이고 μ‹€μ „μ—μ„œ μ–΄λ–»κ²Œ μ“°μ΄λŠ”μ§€ κΆκΈˆν•˜μ‹œλ‹€λ©΄ 2번 링크λ₯Ό ν΄λ¦­ν•΄μ„œ ν™•μΈν•΄μ£Όμ‹œκΈ° λ°”λžλ‹ˆλ‹€.


였늘 μ•Œμ•„λ³Ό 것은 λ°”λ‘œ Generic(μ œλ„ˆλ¦­)으둜 λΆˆλ¦¬λŠ” 것이닀.

 

μ œλ„ˆλ¦­μ„ μ‚¬μš©ν•˜λŠ” μ΄μœ μ™€ 방법에 λŒ€ν•΄μ„œλŠ” μ•Œκ² λŠ”λ° μ‹€μ „μ—μ„œ λ–€ 클래슀λ₯Ό μ œλ„ˆλ¦­μœΌλ‘œ μ§€μ •ν•΄μ•Ό ν• μ§€ λͺ¨λ₯΄κ² κ±°λ‚˜ κΆκΈˆν•˜λ‹€λ©΄ 이번 μ‹œλ¦¬μ¦ˆκ°€ 큰 도움이 λ˜μ§€ μ•Šμ„κΉŒ μƒκ°ν•œλ‹€.

 

μ‹œμž‘ν•΄λ³΄μž.

Generic

μ œλ„ˆλ¦­μ€ Java 1.5 버전뢀터 μΆ”κ°€λ˜μ—ˆμœΌλ©° 뭐 이런 μ΄μ•ΌκΈ°λŠ” μž μ‹œ μ ‘μ–΄ 두고 μ œλ„ˆλ¦­μ΄ 무엇이며 μ™œ μ œλ„ˆλ¦­μ„ μ‚¬μš©ν•΄μ•Ό ν•˜λŠ”μ§€λ₯Ό μ•Œμ•„μ•Όν•œλ‹€.



μ œλ„ˆλ¦­μ΄λž€?

μ‰½κ²Œ νƒ€μž…μ„ νŒŒλΌλ―Έν„°λ‘œ κ°€μ§€λŠ” ν΄λž˜μŠ€μ™€ μΈν„°νŽ˜μ΄μŠ€μ΄λ©° 이름 뒀에 <> κ°€ λΆ™λŠ”λ‹€. 라고 ν•΄λ‘μž.


μ˜λ―Έλ‘ μ μœΌλ‘œλŠ” 더 λ‹€μ–‘ν•˜κ²Œ μ„€λͺ…ν•  수 μžˆμ§€λ§Œ 백문이 λΆˆμ—¬μΌκ²¬μ΄λΌ ν•œ 번 λ³΄λŠ” 것이 백번의 μ„€λͺ…보닀 λ‚«λ‹€.

 

μ œλ„ˆλ¦­μ˜ μž₯점

  • 컴파일 μ‹œμ— κ°•ν•œ νƒ€μž… 체크λ₯Ό ν•  수 μžˆλ‹€.
  • Casting μ œκ±°ν•œλ‹€.

컴파일 μ‹œμ— κ°•ν•œ νƒ€μž… 체크λ₯Ό ν•  수 μžˆλ‹€.

μžλ°” μ»΄νŒŒμΌλŸ¬λŠ” μš°λ¦¬κ°€ μ½”λ“œλ₯Ό μž‘μ„±ν•˜λŠ” μ‹œμ μ— λ°œμƒν•  수 μžˆλŠ” λ¬Έμ œμ μ„ μ œκΈ°ν•΄μ€€λ‹€.


예λ₯Ό λ“€μ–΄μ„œ

 

LinkedList<String> list = new LinkedList<>()λΌλŠ” ꡬ문이 있으면 μš°λ¦¬λŠ” λ‹Ήμ—°νžˆ

listλΌλŠ” λ³€μˆ˜μ—λŠ” String νƒ€μž…λ§Œ λ“€μ–΄κ°ˆ 수 μžˆλ‹€λŠ” 것을 μ•Œ 수 μžˆλ‹€.

 

μ™œλƒ? λ°”λ‘œ νƒ€μž… νŒŒλΌλ―Έν„°κ°€ String으둜 μ§€μ •λ˜μ–΄ 있기 λ•Œλ¬Έμ΄λ‹€.

 

ν•˜μ§€λ§Œ μ œλ„ˆλ¦­ νƒ€μž… νŒŒλΌλ―Έν„°μ— λ²—μ–΄λ‚œ νƒ€μž…μ„ μ œκ³΅ν•œλ‹€λ©΄ 컴파일 μ‹œμ μ— λ‹€μŒκ³Ό 같은 였λ₯˜λ₯Ό λ‚΄λΏœλŠ”λ‹€.

이런 μ‹μœΌλ‘œ 컴파일 μ‹œμ μ— νƒ€μž… 체크λ₯Ό κ°•μ œν™” ν•  수 있고 이 말은 μžμ—°μŠ€λŸ½κ²Œ μ½”λ“œμ˜ 정확성이 λ†’μ•„μ§„λ‹€λŠ” μž₯점이 λœλ‹€.

Casting이 μ œκ±°λœλ‹€.

μΊμŠ€νŒ…μ€ μš°λ¦¬κ°€ ν˜• λ³€ν™˜μ„ μœ„ν•œ 방법쀑 ν•˜λ‚˜λ‘œ μ•Œκ³  μžˆλ‹€.

 

예λ₯Ό λ“€μ–΄μ„œ BoxλΌλŠ” ν΄λž˜μŠ€μ— String을 set ν•΄μ£Όκ³  get λ©”μ„œλ“œλ₯Ό ν†΅ν•΄μ„œ λ“€μ–΄κ°„ String을 좜λ ₯ν•˜λŠ” λ‘œμ§μ„ κ΅¬ν˜„ν•œλ‹€κ³  ν–ˆμ„ λ•Œ μš°λ¦¬λŠ”

class Box {

    private String data;

    void setData(String data) {
        this.data = data;
    }

    String getData() {
        return data;
    }
}

μ΄λ ‡κ²Œ κ΅¬ν˜„ν•  수 μžˆλ‹€.

 

ν•˜μ§€λ§Œ BoxλΌλŠ” ν΄λž˜μŠ€μ— Integerν˜• νƒ€μž…μ˜ λ³€μˆ˜κ°€ λ“€μ–΄κ°ˆ μˆ˜λ„ 있고, Double νƒ€μž…μ˜ λ³€μˆ˜κ°€ λ“€μ–΄κ°ˆ μˆ˜λ„ μžˆλ‹€λ©΄ μš°λ¦¬λŠ” μ–΄λ–€ νƒ€μž…μ΄ μ˜¬μ§€ λͺ¨λ₯΄λ‹ˆ Object νƒ€μž…μœΌλ‘œ λ°›μ•„μ„œ Object νƒ€μž…μœΌλ‘œ λ°˜ν™˜μ‹œν‚€λ©΄ μ‚¬μš©ν•  λ•Œμ— ν˜•λ³€ν™˜ 과정이 ν•„μˆ˜μ μœΌλ‘œ 이루어져야 ν•œλ‹€.

ν•˜μ§€λ§Œ μ—¬κΈ°μ„œ μ œλ„ˆλ¦­μ„ μ‚¬μš©ν•œλ‹€λ©΄

λ³΄λŠ” 것과 같이 ν˜•λ³€ν™˜μ˜ λΆˆν•„μš”ν•œ μ˜€λ²„ν—€λ“œλ₯Ό 쀄일 수 μžˆμ–΄ 전체 μ„±λŠ₯을 μ‘°κΈˆμ΄λ‚˜λ§ˆ μƒμŠΉμ‹œν‚¬ 수 있게 λœλ‹€.

 

μ΄λ ‡κ²Œ μ œλ„ˆλ¦­μ„ μ‚¬μš©ν•œλ‹€λ©΄ 쑰금 더 μš°μ•„ν•œ μ½”λ“œλ₯Ό 생성할 수 있게 λœλ‹€.

 

그럼 기본에 λŒ€ν•΄μ„œλŠ” μ•Œμ•˜κ³  이제 λͺ‡ κ°€μ§€μ˜ λ”μš± μš°μ•„ν•œ λ°©λ²•μ˜ μ œλ„ˆλ¦­μ„ μ•Œμ•„λ³΄μž.

두 개의 μ œλ„€λ¦­ νƒ€μž…μ„ μ‚¬μš©ν•˜κΈ°

μ œλ„€λ¦­μ—μ„œλŠ” 두 개 μ΄μƒμ˜ νƒ€μž…μ— λŒ€ν•΄μ„œ λ©€ν‹° νƒ€μž… νŒŒλΌλ―Έν„°λ₯Ό μ‚¬μš©ν•  수 μžˆλ‹€.


이것도 말이 μ–΄λ ΅μ§€ μ‹€μ œλ‘œ μ—¬λŸ¬λΆ„λ“€μ΄ μ‚¬μš©ν•˜κ³  있던 것 일 μˆ˜λ„ μžˆλ‹€.

 

HashMap<String, Integer> map = new HashMap<>();

 

ν•΄μ‹œλ§΅μ„ μ΄μš©ν•΄μ„œ Key: value 의 객체λ₯Ό λ§Œλ“€κΈ° μœ„ν•΄μ„œ μ‚¬μš©ν•˜λŠ” λ°”λ‘œ 이 ꡬ쑰가 λ©€ν‹° νƒ€μž… νŒŒλΌλ―Έν„°μ˜ λŒ€ν‘œμ μΈ 예 이닀.

 

μ—¬κΈ°μ„œ μ•Œμ•„λ‘λ©΄ μ–Έμ  κ°„ μ“Έλͺ¨κ°€ μžˆλŠ” 지식이 μžˆλ‹€λ©΄ μžλ°” 6버전 μ΄μ „λΆ€ν„°λŠ” λ©€ν‹° νƒ€μž…μ— 일일이 ꡬ체적 νƒ€μž…μ„ μ§€μ •ν•΄μ€¬μ—ˆλ‹€.

 

λ°”λ‘œ μ΄λ ‡κ²Œ

 

HashMap<String, Integer> map = new HashMap<String, Integer>();

 

ν•˜μ§€λ§Œ μš°λ¦¬κ°€ λ„ˆλ¬΄λ‚˜λ„ μ‹«μ–΄ν•˜λŠ” μ½”λ“œμ˜ 쀑볡이 λ°œμƒν•˜κ³  μ½”λ“œκ°€ λ”λ €μ›Œμ§ˆ 수 μžˆλ‹€λŠ” 이유둜 μžλ°” 7λΆ€ν„°λŠ” 닀이아λͺ¬λ“œ μ—°μ‚°μžλ₯Ό μ΄μš©ν•΄μ„œ νƒ€μž…μ„ μžλ™μœΌλ‘œ μœ μΆ”ν•  수 있기 λ•Œλ¬Έμ— μš°λ¦¬λŠ” ν˜„μž¬μ˜ 이 HashMap<String, Integer> map = new HashMap<>(); μš°μ•„ν•œ μ½”λ“œλ₯Ό μ‚¬μš©ν•  수 μžˆλŠ” 것이닀.

μ œλ„ˆλ¦­ λ©”μ„œλ“œ

μ œλ„ˆλ¦­ λ©”μ„œλ“œλŠ” 맀개 νƒ€μž…κ³Ό 리턴 νƒ€μž…μœΌλ‘œ νƒ€μž… νŒŒλΌλ―Έν„°λ₯Ό κ°–λŠ” λ©”μ„œλ“œμ΄λ‹€.

 

보톡 클래슀λ₯Ό μ„ μ–Έν•˜μ§€ μ•Šκ³  μ“Έ 수 μžˆλŠ” static λ©”μ„œλ“œμ— 자주 쓰이곀 ν•˜λŠ”λ° 그도 그럴 것이,


클래슀λ₯Ό μ„ μ–Έν•˜μ§€ μ•ŠμœΌλ©΄ μ œλ„€λ¦­μ„ μ‚¬μš©ν•  ν•΄λ‹Ή ν΄λž˜μŠ€κ°€ μ–΄λ–€ 클래슀λ₯Ό 받을 수 μžˆλŠ”μ§€ 직접 μ§€μ •ν•  수 μ—†κΈ° λ•Œλ¬Έμ— λ©”μ„œλ“œ λ‹¨μœ„μ—μ„œ 컴파일 체크λ₯Ό 해쀄 수 있게 ν•˜κΈ° μœ„ν•΄ μ‚¬μš©λœλ‹€.

public class Pair<K, V> {
    private K key;
    private V value;

    public Pair(K key, V value) {
        this.key = key;
        this.value = value;
    }

    public void setKey(K key) { this.key = key; }
    public void setValue(V value) { this.value = value; }
    public K getKey()   { return key; }
    public V getValue() { return value; }
}

public class Util {
    public static <K, V> boolean compare(Pair<K, V> p1, Pair<K, V> p2) {
        return p1.getKey().equals(p2.getKey()) &&
                p1.getValue().equals(p2.getValue());
    }
}
ν•΄λ‹Ή μ†ŒμŠ€μ½”λ“œλŠ” λΉ λ₯Έ μ„€λͺ…을 μœ„ν•΄ 백쀑원 κ°œλ°œμžλ‹˜μ˜ medium λΈ”λ‘œκ·Έμ—μ„œ κ°€μ Έμ™”μŠ΅λ‹ˆλ‹€. 좜처

백쀑원 κ°œλ°œμžλ‹˜μ΄ μž‘μ„±ν•˜μ‹  μ†ŒμŠ€μ½”λ“œλ₯Ό 보자면 Util ν΄λž˜μŠ€μ—μ„œ static으둜 compareμ΄λΌλŠ” λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜κΈ° μœ„ν•΄μ„œ λ°˜ν™˜ νƒ€μž…μœΌλ‘œ <K, V>의 μ œλ„€λ¦­λ§Œ μ‚¬μš©ν•  수 μžˆλ„λ‘ ν•˜μ˜€λ‹€.

 

보톡 이런 경우의 μ‚¬μš© 방법은

<μ œλ„€λ¦­ νƒ€μž… νŒŒλΌλ―Έν„°> λ°˜ν™˜ νƒ€μž… λ©”μ„œλ“œ 이름 (λ§€κ°œλ³€μˆ˜) {...}

의 ν˜•νƒœλ‘œ μ‚¬μš©ν•˜κ³€ ν•œλ‹€.


μ΄λ ‡κ²Œ μ˜€λŠ˜μ€ 기본적인 μ œλ„€λ¦­μ„ μ‚¬μš©ν•˜λŠ” 방법에 λŒ€ν•΄μ„œ μ•Œμ•„λ³΄μ•˜λ‹€.

λ‹€μŒμ‹œκ°„μ—λŠ” 쑰금 더 깊게 λ“€μ–΄κ°€μ„œ

? ν˜•νƒœμ˜ μ™€μΌλ“œ μΉ΄λ“œμ— λŒ€ν•΄μ„œλ„ μ•Œμ•„λ³΄κ³  쑰금 이둠적인 심화 λ‚΄μš©μ„ ν•œ 번 λ‹€λ€„λ³΄μž.

μ˜€λŠ˜μ€ μΆ©λΆ„ν•˜λ‹€.