JAVA

[Java] μ œλ„€λ¦­

YeopJu 2024. 6. 11. 20:41
λ°˜μ‘ν˜•

2024λ…„ μƒλ°˜κΈ° λ©΄μ ‘ μ‹œμ¦Œμ΄ λλ‚˜κ³  λ‹€μ‹œ 곡뢀λ₯Ό μ‹œμž‘ν–ˆλ‹€πŸ₯² κ°€μž₯ μ΅œκ·Όμ— λ³Έ λ©΄μ ‘μ—μ„œ μ œλ„€λ¦­μ— λŒ€ν•΄ κ°„λ‹¨ν•˜κ²Œ μ„€λͺ…ν•˜λΌλŠ” μ§ˆλ¬Έμ„ λ°›μ•˜κ³ , 이에 λ‚˜λŠ” 'κ°•νƒ€μž… 언어인 μžλ°”μ˜ κ°€μš©μ„±μ„ λŠ˜λ €μ€„ 수 μžˆλŠ” 기술둜 λ²”μš© ν΄λž˜μŠ€μ™€ λ©”μ„œλ“œλ₯Ό λ§Œλ“€ 수 있게 ν•΄μ€€λ‹€' 라고 λ‹΅ν–ˆλ‹€. 반μͺ½μ§œλ¦¬ λ‹΅λ³€μ΄μ—ˆκ³  이 λ•Œ λ‚΄κ°€ μˆœκ°„μ μœΌλ‘œ λ– μ˜¬λ¦° 것은 μ œλ„€λ¦­μ˜ μ™€μΌλ“œμΉ΄λ“œ, 즉 `?` ν‚€μ›Œλ“œμ˜€λ‹€. λ§Œμ•½ 이에 λŒ€ν•΄μ„œ 꼬리질문이 λ“€μ–΄μ™”λ‹€λ©΄ λ‚˜λŠ” 쀄쀄이 ν‹€λ¦° 닡변을 ν–ˆμ„ 것이고 μ œλ„€λ¦­μ— λŒ€ν•΄μ„œ μžμ„Έν•˜κ²Œ λͺ¨λ₯Έλ‹€λŠ” 생각이 λ“€μ—ˆλ‹€. κ·Έλž˜μ„œ μ˜€λŠ˜μ€ μ œλ„€λ¦­μ— λŒ€ν•΄μ„œ κ³΅λΆ€ν•œ λ‚΄μš©μ„ μ •λ¦¬ν•΄λ³΄κ³ μž ν•œλ‹€.

 


 

 

β˜‘οΈ μ œλ„€λ¦­

μ œλ„€λ¦­μ€ μΊμŠ€νŒ…μœΌλ‘œ 인해 λ°œμƒν•˜λŠ” μ˜€λ²„ν—€λ“œλ₯Ό 쀄이고 κ°€μš©μ„±μ„ 늘리기 μœ„ν•΄ κ°œλ°œν•œ λ¬Έλ²•μœΌλ‘œ 클래슀 λ‚΄λΆ€μ—μ„œ μ‚¬μš©ν•  νƒ€μž…μ„ μ™ΈλΆ€μ—μ„œ μ§€μ •ν•˜λŠ” 것을 μ˜λ―Έν•œλ‹€.

μ œλ„€λ¦­μ€ `<>` 닀이아λͺ¬λ“œ μ—°μ‚°μž 자체λ₯Ό μ˜λ―Έν•˜λ©° `<>` 내뢀에 λ“€μ–΄κ°€λŠ” `T`, `U`, `?`, `Reference Type` 등은 μ œλ„€λ¦­μ˜ νƒ€μž… λ§€κ°œλ³€μˆ˜λΌκ³  λΆ€λ₯Έλ‹€.

 

 

β˜‘οΈ μ œλ„€λ¦­ λ©”μ„œλ“œ

μ œλ„€λ¦­ λ©”μ„œλ“œλž€ λ©”μ„œλ“œ 선언뢀에 직접 μ œλ„€λ¦­ `<T>`λ₯Ό μ„ μ–Έν•œ λ©”μ„œλ“œλ₯Ό λ§ν•œλ‹€. 클래슀 νƒ€μž… λ§€κ°œλ³€μˆ˜λ₯Ό μ‚¬μš©ν•œ λ©”μ„œλ“œμ™€ ν˜Όλ™ν•  κ°€λŠ₯성이 λ†’κΈ° λ•Œλ¬Έμ— μ£Όμ˜ν•΄μ•Όν•œλ‹€.

μ•„λž˜ μ½”λ“œμ™€ 같은 μ œλ„€λ¦­ λ©”μ„œλ“œλ₯Ό 보고 생길 수 μžˆλŠ” μ˜λ¬Έμ μ€ '같은 νƒ€μž… νŒŒλΌλ―Έν„° 기호λ₯Ό μ‚¬μš©ν•˜λŠ”λ° μ–΄λ–»κ²Œ λ³„κ°œμ˜ μ œλ„€λ¦­μœΌλ‘œ μ‚¬μš©λ˜λŠ”κ°€' 이닀.

class Test<T>{
	public T JustMethod(T n){}
    public <T> void GenericMethod(T n){}
}

 

사싀 μ œλ„€λ¦­ λ©”μ„œλ“œλŠ” 클래슀 μΈμŠ€ν„΄μŠ€κ°€ 선언될 경우 클래슀의 νƒ€μž… λ§€κ°œλ³€μˆ˜μ™€ 같은 νƒ€μž…μ„ μ‚¬μš©ν•˜μ—¬ μƒμ„±λœλ‹€. ν•˜μ§€λ§Œ μ•„λž˜μ™€ 같이 μ œλ„€λ¦­ ν΄λž˜μŠ€κ°€ μ„ μ–Έλœ ν›„ μ œλ„€λ¦­ λ©”μ„œλ“œ νƒ€μž… νŒŒλΌλ―Έν„°μ˜ νƒ€μž…μ„ λ³„λ„λ‘œ 지정해쀄 경우, 독립적인 νƒ€μž…μ„ κ°€μ§„ μ œλ„€λ¦­ λ©”μ„œλ“œλ‘œμ„œ 운용될 수 μžˆλŠ” 것이닀.

 

class Test<T, U> {
    public <T, U> void running(T x, U y) {}
}

public static void main(String[] args) {
    Test<Integer, Long> test = new Test<>();
    test.running(1, 1); // <Integer, Long>

    test.<String, Double>running("Yeop", 30.0);
}

 

 

β˜‘οΈ μ œλ„€λ¦­μ˜ νŠΉμ§•

1️⃣ static 객체

static λ©”μ„œλ“œμ—λŠ” ν΄λž˜μŠ€μ—μ„œ μ„ μ–Έν•œ μ œλ„€λ¦­ μ‚¬μš©μ΄ λΆˆκ°€λŠ₯ν•˜λ‹€. μ΄λŠ” 클래슀 μΈμŠ€ν„΄μŠ€μ™€ 생λͺ…μ£ΌκΈ°κ°€ λ‹€λ₯΄κΈ° λ•Œλ¬ΈμœΌλ‘œ static λ©”μ„œλ“œμ—μ„œ μ œλ„€λ¦­μ„ μ‚¬μš©ν•˜κΈ° μœ„ν•΄μ„œλŠ” static λ©”μ„œλ“œλ₯Ό static μ œλ„€λ¦­ λ©”μ„œλ“œλ‘œ μƒμ„±ν•΄μ•Όν•œλ‹€.

class Test<T>{
	static T impossible(int n){} // λΆˆκ°€λŠ₯
    static <T> void possible(T[] array){} // κ°€λŠ₯
}

 

2️⃣ 볡수 νƒ€μž…, 쀑첩 νƒ€μž… μ„ μ–Έ κ°€λŠ₯

Class Test<T, U>{} // 볡수 μ„ μ–Έ
LinkedList<ArrayList<Integer>> list = new LinkedList<ArrayList<Integer>>(); // 쀑첩 μ„ μ–Έ

   

 

β˜‘οΈ μ œλ„€λ¦­ νƒ€μž… λ²”μœ„

μ œλ„€λ¦­μ€ λ²”μš©μ„±κ³Ό κ°€μš©μ„±μ„ 크게 μ¦κ°€μ‹œμΌœμ£Όμ§€λ§Œ λ„ˆλ¬΄ μžμœ λ‘­λ‹€λŠ” 단점과 곡변성이 λΆ€λΆ„μ μœΌλ‘œ μ μš©λœλ‹€λŠ” 문제점이 μ‘΄μž¬ν•œλ‹€. 이λ₯Ό λ³΄μ™„ν•˜κΈ° μœ„ν•œ 것이 각각`extends, super` ν‚€μ›Œλ“œμ™€ μ™€μΌλ“œμΉ΄λ“œμ΄λ‹€.

 

`extends`와 `super` ν‚€μ›Œλ“œκ°€ μ™€μΌλ“œ μΉ΄λ“œμ™€ ν•¨κ»˜ μ‚¬μš©λ  κ²½μš°μ—λŠ” ν˜Όλ™λ˜λŠ” κ°œλ…μ„ ν¬ν•¨ν•˜κ³  있기 λ•Œλ¬Έμ— λ¨Όμ € 일반적인 νƒ€μž… λ§€κ°œλ³€μˆ˜μ™€ ν•¨κ»˜ μ‚¬μš©λ˜λŠ” κ²½μš°μ— λŒ€ν•΄ κ°„λ‹¨νžˆ 닀룬 ν›„ μ™€μΌλ“œ μΉ΄λ“œμ˜ μƒν•œ 경계와 ν•˜ν•œ 경계에 λŒ€ν•΄ μ„€λͺ…ν•˜κ³ μž ν•œλ‹€. 

 

1️⃣ μ œλ„€λ¦­μ˜ μƒν•œκ²½κ³„

 

'extends' ν‚€μ›Œλ“œλŠ” μƒμœ„ νƒ€μž…μ„ μ œν•œν•˜μ—¬ μ§€μ • νƒ€μž…κ³Ό κ·Έ ν•˜μœ„ νƒ€μž…λ“€λ§Œ 받도둝 ν•˜λŠ” 것이닀. μ œλ„€λ¦­μ˜ extends ν‚€μ›Œλ“œ λ’€μ—λŠ” 일반 클래슀, 좔상 클래슀, μΈν„°νŽ˜μ΄μŠ€ λͺ¨λ‘ 올 수 있으며 λ‹€μŒκ³Ό 같이 `&` ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ 닀쀑 μ œν•œμ΄ κ°€λŠ₯ν•˜λ‹€.

interface peach {}
interface apple {}

class FruitType implements Peach, Apple {}

class Fruit<T extends Peach & Apple> {}

 

λ˜ν•œ μž¬κ·€μ  νƒ€μž… ν•œμ •μ΄ κ°€λŠ₯ν•œλ°, μž¬κ·€μ  νƒ€μž… ν•œμ •μ΄λž€ 자기 μžμ‹ μ΄ λ“€μ–΄κ°„ λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ νƒ€μž… λ§€κ°œλ³€μˆ˜λ₯Ό νƒ€μž… λ²”μœ„λ₯Ό μ œν•œν•˜λŠ” 것을 λ§ν•œλ‹€. μ‹€λ¬΄μ—μ„œλŠ” 주둜 Comparable μΈμŠ€ν„΄μŠ€μ™€ ν•¨κ»˜ μ‚¬μš©λœλ‹€. `<E extends Comparable<E>>`

 

 

2️⃣ μ œλ„€λ¦­μ˜ ν•˜ν•œκ²½κ³„

'super' ν‚€μ›Œλ“œλŠ” μ§€μ • νƒ€μž…κ³Ό κ·Έ μƒμœ„ νƒ€μž…λ“€λ§Œ 받도둝 μ œν•œν•œλ‹€. `super` ν‚€μ›Œλ“œλŠ” μ™€μΌλ“œμΉ΄λ“œκ°€ μ•„λ‹Œ νƒ€μž… λ§€κ°œλ³€μˆ˜μ™€ ν•¨κ»˜ λ‹€μŒκ³Ό 같이 μ‚¬μš©ν•œλ‹€λ©΄ `<T super U>` Object와 μœ μ‚¬ν•œ 역할을 ν•˜κ²Œ 되기 λ•Œλ¬Έμ— 일반적으둜 잘 μ‚¬μš©λ˜μ§€ μ•ŠλŠ”λ‹€.

 

 

3️⃣ μ™€μΌλ“œ μΉ΄λ“œ

μ œλ„€λ¦­μ˜ μ™€μΌλ“œ μΉ΄λ“œλŠ” `?` ν‚€μ›Œλ“œλ‘œ μ„ μ–Έν•˜λ©° 일반적인 νƒ€μž… μ„ μ–Έμ—μ„œμ˜ Object와 같은 역할을 ν•œλ‹€. 각 객체 κ°„μ—λŠ” 곡변성이 μ‘΄μž¬ν•˜κΈ° λ•Œλ¬Έμ— κ°€μž₯ μƒμœ„ 객체인 Objectλ₯Ό μ„ μ–Έν•œλ‹€λ©΄ μΊμŠ€νŒ…μ„ 톡해 μœ μ—°ν•˜κ²Œ νƒ€μž…μ„ μ μš©ν•  수 μžˆλ‹€. ν•˜μ§€λ§Œ μ œλ„€λ¦­μ€ λ¬΄κ³΅λ³€μ˜ μ„±μ§ˆμ„ 띄기 λ•Œλ¬Έμ— 항상 전달받은 ν•˜λ‚˜μ˜ νƒ€μž…μœΌλ‘œλ§Œ μ‚¬μš©ν•  수 있기 λ•Œλ¬Έμ— 객체 μ§€ν–₯의 μž₯점을 μ „ν˜€ μ΄μš©ν•˜μ§€ λͺ»ν•œλ‹€. 이λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄ μ™€μΌλ“œ μΉ΄λ“œκ°€ ν•„μš”ν•œ 것이닀.

 

 

μ•„λž˜μ™€ 같이 μ™€μΌλ“œ μΉ΄λ“œμ™€ 경계 μ œν•œ ν‚€μ›Œλ“œλ₯Ό ν™œμš©ν•˜λ©΄ μ œλ„€λ¦­μ— 곡변성과 λ°˜κ³΅λ³€μ„±μ„ 적절히 λΆ€μ—¬ν•  수 μžˆλ‹€.

ArrayList<? extends Animal> animals = new ArrayList<Dog>(); // 곡변
ArrayList<? super Dog> dogs = new ArrayList<Animal>(); // λ°˜κ³΅λ³€

 

일반적으둜 μ™€μΌλ“œ μΉ΄λ“œλŠ” μ œλ„€λ¦­ νƒ€μž… μ œν•œ ν‚€μ›Œλ“œμΈ `extends`, `super`와 ν•¨κ»˜ λ‹€μŒκ³Ό 같이 쓰이며 각 κ²½μš°λŠ” μ—£μ§€ μΌ€μ΄μŠ€λ₯Ό λ– μ˜¬λ¦¬λ©° 생각해 λ³Ό ν•„μš”κ°€ μžˆλ‹€.

 

 

μƒν•œ 경계  List<? extends U>

  • GET : μ•ˆμ „ν•˜κ²Œ κΊΌλ‚΄λ €λ©΄ U νƒ€μž…μœΌλ‘œ λ°›μ•„μ•Όν•œλ‹€. (EX - for λ¬Έ μ‚¬μš©ν•  경우)
  • SET : μ–΄λ– ν•œ νƒ€μž…μ˜ μžλ£Œλ„ λ„£μ„μˆ˜ μ—†λ‹€. (null만 μ‚½μž… κ°€λŠ₯)

ν•˜ν•œ 경계 List<? super U>

  • GET : μ•ˆμ „ν•˜κ²Œ κΊΌλ‚΄λ €λ©΄ Object νƒ€μž…μœΌλ‘œλ§Œ λ°›μ•„μ•Όν•œλ‹€.
  • SET : U와 U의 ν•˜μœ„ νƒ€μž…λ§Œ 넣을 수 μžˆλ‹€.

비경계 List<?>

  • GET : μ•ˆμ „ν•˜κ²Œ κΊΌλ‚΄λ €λ©΄ Object νƒ€μž…μœΌλ‘œλ§Œ λ°›μ•„μ•Όν•œλ‹€. (super 의 νŠΉμ§•)
  • SET : μ–΄λ– ν•œ νƒ€μž…μ˜ μžλ£Œλ„ λ„£μ„μˆ˜ μ—†λ‹€. (null만 μ‚½μž… κ°€λŠ₯) (extends 의 νŠΉμ§•)

 

 

μΆ”κ°€μ μœΌλ‘œ νƒ€μž… μ œν•œμ— λŒ€ν•œ PECSλΌλŠ” 곡식이 μžˆλŠ”λ° μ΄λŠ” Producer - Extends / Consumer - Super 의 μ•½μžλ‘œ λ©”μ„œλ“œκ°€ 데이터λ₯Ό μƒμ‚°ν•œλ‹€λ©΄ `extends`, μ†ŒλΉ„ν•œλ‹€λ©΄ `super`λ₯Ό μ‚¬μš©ν•΄μ•Όν•œλ‹€λŠ” 의미λ₯Ό κ°€μ§€κ³  μžˆλ‹€. ν•˜μ§€λ§Œ ν•΄λ‹Ή 곡식을 μ§κ΄€μ μœΌλ‘œ μ μš©ν•˜κΈ°μ—λŠ” 무리가 μžˆλ‹€κ³  μƒκ°ν•œλ‹€. 

 


μ œλ„€λ¦­μ€ νƒ€μž… μ•ˆμ •μ„±κ³Ό μΊμŠ€νŒ… μ˜€λ²„ν—€λ“œ κ°œμ„ μ„ μœ„ν•΄ JDK 1.5λΆ€ν„° λ„μž…λœ 문법이닀. κ·Έλ ‡κΈ° λ•Œλ¬Έμ— 이전 버전과 ν˜Έν™˜μ„ μœ„ν•΄ 컴파일 κ³Όμ • 이후 클래슀 νŒŒμΌμ—μ„œλŠ” λͺ¨λ‘ Object νƒ€μž…μœΌλ‘œ λ³€ν™˜λ˜κ±°λ‚˜ μ œκ±°λœλ‹€.

 

 


 

β˜‘οΈ κ²°λ‘ 

μ œλ„€λ¦­ λ©”μ„œλ“œ 뢀뢄을 κ³΅λΆ€ν•˜λ©΄μ„œ λΆ„λͺ…νžˆ 전에도 μ œλ„€λ¦­μ— λŒ€ν•΄μ„œ κ³΅λΆ€ν•œ 것 같은 λŠλ‚Œμ΄ λ“€μ—ˆμ§€λ§Œ, 이정도면 μ œλ„€λ¦­μ— λŒ€ν•΄μ„œ μ „ν˜€ λͺ¨λ₯΄κ³  μžˆμ—ˆλ‹€κ³  해도 ν•  말이 없을 μˆ˜μ€€μ΄λ‹€.. 특히 μ™€μΌλ“œμΉ΄λ“œ 경계λ₯Ό 개발 상황에 μ μ ˆν•˜κ²Œ μ μš©ν•˜κΈ° μœ„ν•΄μ„œλŠ” μ—¬λŸ¬ μ—£μ§€ μΌ€μ΄μŠ€λ₯Ό κ³ λ €ν•΄λ³Ό ν•„μš”κ°€ μžˆμ„ 것 κ°™λ‹€.

λ°˜μ‘ν˜•