generics

  • ์ง€๋„ค๋ฆญ์Šค๋Š” JDK1.5์—์„œ ์ฒ˜์Œ ๋„์ž…๋˜์—ˆ๋‹ค. ์ด์   ์ง€๋„ค๋ฆญ์Šค๋ฅผ ๋ชจ๋ฅด๊ณ ๋Š” JAVA API๋ฌธ์„œ๋ฅผ ์ œ๋Œ€๋กœ ๋ณด๊ธฐ ์–ด๋ ค์šธ๋งŒํผ ์ค‘์š”ํ•œ์œ„์น˜๋ฅผ ์ฐจ์ง€ํ•˜์˜€๋‹ค.

์ง€๋„ค๋ฆญ์Šค๋ž€?

  • ๋ฉ”์„œ๋“œ๋‚˜ ์ปฌ๋ ‰์…˜ํด๋ž˜์Šค์— ์ปดํŒŒ์ผ์‹œ์˜ ํƒ€์ž…์ฒดํฌ๋ฅผ ํ•ด์ฃผ๋Š” ๊ธฐ๋Šฅ์ด๋‹ค.

  • ๊ฐ์ฒด์˜ ํƒ€์ž… ์•ˆ์ •์„ฑ์„ ๋†’์ด๊ณ  ํ˜•๋ณ€ํ™˜์˜ ๋ฒˆ๊ฑฐ๋กœ์›€์„ ์ค„์—ฌ์ค€๋‹ค.

  • ํƒ€์ž…์•ˆ์ •์„ฑ = ์˜๋„ํ•˜์ง€ ์•Š์€ ํƒ€์ž…์˜ ๊ฐ์ฒด๊ฐ€ ์ €์žฅ๋˜๋Š”๊ฒƒ์„ ๋ง‰๊ณ  ์ €์žฅ๋œ ๊ฐ์ฒด๋ฅผ ๊บผ๋‚ด์˜ฌ๋•Œ ์›๋ž˜์˜ ํƒ€์ž…๊ณผ ๋‹ค๋ฅธ ํƒ€์ž…์œผ๋กœ ์ž˜๋ชป ํ˜•๋ณ€ํ™˜๋˜์–ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์˜ค๋ฅ˜๋ฅผ ์ค„์—ฌ์ค€๋‹ค.

์ง€๋„ค๋ฆญ ํด๋ž˜์Šค ์„ ์–ธ

class Box<T> {
	T item;

	void setItem(T item){
		this.item = item;
	}
	T getItem() { 
		return item; 
	}
}
  • T : ํƒ€์ž…๋ณ€์ˆ˜, T๊ฐ€ ์•„๋‹Œ ๋‹ค๋ฅธ๊ฒƒ์„ ์‚ฌ์šฉํ•ด๋„ ๋œ๋‹ค. ์ด๋Š” ์ž„์˜์˜ ์ฐธ์กฐํ˜• ํƒ€์ž…์„ ์˜๋ฏธํ•œ๋‹ค.

  • ๊ธฐ์กด์—๋Š” Object๋กœ ์ฐธ์กฐ๋ณ€์ˆ˜๋ฅผ ๋งŽ์ด ์‚ฌ์šฉํ–ˆ๋Š”๋ฐ ๊ทธ๋กœ์ธํ•ด ํ˜•๋ณ€ํ™˜์ด ๋ถˆ๊ฐ€ํ”ผ ํ–ˆ๋‹ค ํ—ˆ๋‚˜ ์ด์   Object ๋Œ€์‹  ์›ํ•˜๋Š” ํƒ€์ž…์„ ์ง€์ •ํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋œ๋‹ค.

ํƒ€์ž…์„ ์ง€์ •ํ•ด์ฃผ์ง€ ์•Š์„๋•Œ

Box b = mew Box(); // T๊ฐ€ Object๋กœ ๊ฐ„์ฃผ๋˜์–ด ํ—ˆ์šฉ๋œ๋‹ค.
b.setItem("ABC"); // ๊ฒฝ๊ณ 
  • ์œ„์ฒ˜๋Ÿผ ์ง€๋„ค๋ฆญ์ด ๋„์ž…๋˜๊ธฐ ์ด์ „์˜ ์ฝ”๋“œ์™€์˜ ํ˜ธํ™˜์„ ์œ„ํ•ด ์˜ˆ์ „๋ฐฉ์‹์œผ๋กœ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š”๊ฒƒ์ด ํ—ˆ์šฉ๋œ๋‹ค๋งŒ, ํƒ€์ž…์„ ์ง€์ •ํ•˜์ง€ ์•Š์•„ ์•ˆ์ „ํ•˜์ง€ ์•Š๋‹ค๋Š” ๊ฒฝ๊ณ ๊ฐ€ ํ‘œ์‹œ๋œ๋‹ค.

  • ์™ ๋งŒํ•˜๋ฉด ๋ฐ˜๋“œ์‹œ ํƒ€์ž…์„ ์ง€์ •ํ•ด์ฃผ์ž

๋งค๊ฐœ๋ณ€์ˆ˜์™€์˜ ์œ ์‚ฌ์„ฑ

  • Box<String>๊ณผ Box<Integer>๋Š” ์ง€๋„ค๋ฆญ ํด๋ž˜์Šค Box<T>์— ์„œ๋กœ ๋‹ค๋ฅธ ํƒ€์ž…์„ ๋Œ€์ž…ํ•ด ํ˜ธ์ถœํ•œ ๊ฒƒ์ผ ๋ฟ, ์ด ๋‘˜์ด ๋ณ„๊ฐœ์˜ ํด๋ž˜์Šค๋ฅผ ์˜๋ฏธํ•˜์ง€ ์•Š๋Š”๋‹ค. (๊ฐ™์€ ํด๋ž˜์Šค๋ผ๋Š” ๋ง์ด๋‹ค.)

  • ์ปดํŒŒ์ผ ํ›„์— ๋‘˜๋‹ค ๋ชจ๋‘ ์ด๋“ค์˜ ์›์‹œํƒ€์ž…์ธ Box๋กœ ๋ฐ”๋€๋‹ค. ์ง€๋„ค๋ฆญ ํƒ€์ž…์ด ์ œ๊ฑฐ๋œ๋‹ค๋Š” ์˜๋ฏธ์ด๋‹ค.

์ง€๋„ค๋ฆญ ํด๋ž˜์Šค์˜ ์ œํ•œ

  • static ๋ฉค๋ฒ„์— ํƒ€์ž…๋ณ€์ˆ˜ T๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค.

    • T๋Š” ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜๋กœ ๊ฐ„์ฃผ๋˜๋Š”๋ฐ static ๋ฉค๋ฒ„๋Š” ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜๋ฅผ ์ฐธ์กฐํ•  ์ˆ˜ ์—†๋‹ค.

    • static๋ฉค๋ฒ„๋Š” ํƒ€์ž…์ด ๋™์ผํ•œ ๊ฒƒ์ด์—ฌ์•ผ ํ•œ๋‹ค. ์–ด๋–ค ๊ฐ์ฒด์—์„œ ํ˜ธ์ถœํ•ด๋„ ๋ชจ๋‘ ๋™์ผํ•˜๊ฒŒ ๋™์ž‘ํ•˜๋ฉฐ ๊ณต์œ ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

  • ์ง€๋„ค๋ฆญ ํƒ€์ž…์˜ ๋ฐฐ์—ด์„ ์ƒ์„ฑํ•˜๋Š”๊ฒƒ๋„ ํ—ˆ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค.

    • ๊ทธ ์ด์œ ๋Š” new ์—ฐ์‚ฐ์ž ๋•Œ๋ฌธ์ธ๋ฐ ์ด ์—ฐ์‚ฐ์ž๋Š” ์ปดํŒŒ์ผ ์‹œ์ ์— ํƒ€์ž…T๊ฐ€ ๋ญ”์ง€ ์ •ํ™•ํžˆ ์•Œ์•„์•ผํ•œ๋‹ค. Box<T>๋ฅผ ์ปดํŒŒ์ผ ํ•˜๋Š” ์‹œ์ ์— T๊ฐ€ ์–ด๋–ค ํƒ€์ž…์ด ๋ ์ง€ ์•Œ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— instanceof ๋„ ๊ฐ™์€ ์ด์œ ๋กœ ์‚ฌ์šฉํ• ์ˆ˜ ์—†๋‹ค

class Box<T> {
	T[] itemArr;

	T[] toArray() {
		T[] tmpArr = new T[itemArr.length]; //์—๋Ÿฌ ์ง€๋„ค๋ฆญ ๋ฐฐ์—ด ์ƒ์„ฑ๋ถˆ๊ฐ€
		...
	}
}

์ง€๋„ค๋ฆญ ํด๋ž˜์Šค์˜ ๊ฐ์ฒด ์ƒ์„ฑ๊ณผ ์‚ฌ์šฉ

  • Box.java

import java.util.ArrayList;

public class Box<T> {
    ArrayList<T> list =new ArrayList<T>();

    void add(T item) { list.add(item); }
    T get (int i) { return list.get(i); }
    ArrayList<T> getList() { return list; }
    int size() { return list.size(); }
    public String toString() { return list.toString(); }

}
  • FruitBox.java

public class FruitBox<T> extends Box<T>{
}
  • main.java

public class Main {
    public static void main(String[] args) {
        Box<Apple> appleBox = new Box<Apple>();
        Box<Fruit> fruitBox = new Box<Fruit>();

        appleBox.add(new Apple());
        //๋‹น์—ฐํ•˜์ง€๋งŒ Appleํƒ€์ž…์œผ๋กœ ์ƒ์„ฑํ•œ ์ฐธ์กฐ๋ณ€์ˆ˜๋‹ˆ Apple๊ฐ์ฒด๋งŒ ๋„ฃ์„์ˆ˜์žˆ๋‹ค
        //appleBox.add(new Grape());

        //์ƒ์†๊ด€๊ณ„์˜ ํƒ€์ž…๋“ค ๋‹ค ๊ฐ€๋Šฅ, void add(Fruit item)
        fruitBox.add(new Fruit());
        fruitBox.add(new Apple());
        fruitBox.add(new Grape());

        //์ฐธ์กฐ๋ณ€์ˆ˜์™€ ์ƒ์„ฑ์ž์— ๋Œ€์ž…๋œ ํƒ€์ž…์ด ์ผ์น˜ํ•ด์•ผํ•œ๋‹ค. ์ผ์น˜ํ•˜์ง€ ์•Š์œผ๋ฉด ์—๋Ÿฌ
        //Box<Grape> appleBox2 = new Box<Apple>();

        //์ƒ์†๊ด€๊ณ„์— ์žˆ๋”๋ผ๋„ ์—๋Ÿฌ
        //Box<Fruit> FruitBox = new Box<Apple>();

        //์ง€๋„ค๋ฆญ ํด๋ž˜์Šค๊ฐ€ ์ƒ์†๊ด€๊ณ„์— ์žˆ๋Š”๊ฑด ๊ดœ์ฐฎ๋‹ค
        Box<Apple> appleBox1 = new FruitBox<Apple>();
    }
}

class Fruit {
    public String toString(){
        return "Fruit";
    }
}
class Grape extends Fruit{
    public String toString(){
        return "Grape";
    }
}
class Apple extends Fruit{
    public String toString(){
        return "Apple";
    }
}
class Toy {
    public String toString(){
        return "Toy";
    }
}

์ œํ•œ๋œ ์ง€๋„ค๋ฆญ ํด๋ž˜์Šค

  • ๋งค๊ฐœ๋ณ€์ˆ˜ T์— ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋Š” ํƒ€์ž…์˜ ์ข…๋ฅ˜๋ฅผ ์ œํ•œํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•

  • ์ œํ•œํ•˜์ง€ ์•Š์œผ๋ฉด ๋ชจ๋“  ์ข…๋ฅ˜์˜ ํƒ€์ž…์ด ์ง€์ •๋˜๊ธฐ ๋•Œ๋ฌธ์— fruitBox์— Toy๋ฅผ ๋‹ด์„์ˆ˜๋„ ์žˆ๋‹ค

extends ์‚ฌ์šฉ

  • FruitBoxExtendsFruit.java

/**
 * ์ œํ•œ๋œ ์ง€๋„ค๋ฆญ ํด๋ž˜์Šค
 * Fruitํƒ€์ž…๋งŒ ํƒ€์ž… ๋งค๊ฐœ๋ณ€์ˆ˜ T์— ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค
 * ๋‹คํ˜•์„ฑ์—์„œ ์กฐ์ƒํƒ€์ž… ์ฐธ์กฐ๋ณ€์ˆ˜๋กœ ์ž์†ํƒ€์ž… ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚ฌ ์ˆ˜ ์žˆ๋Š”๊ฒƒ ์ฒ˜๋Ÿผ Fruit์™€ ๊ทธ ์ž์† ํƒ€์ž…๊นŒ์ง€ ๊ฐ€๋Šฅํ•˜๋‹ค
 * @param <T>
 */
public class FruitBoxExtendsFruit<T extends Fruit> extends Box {

    ArrayList<T> list = new ArrayList<T>();

}
  • main.java

FruitBoxExtendsFruit<Apple> appleFruitBox = new FruitBoxExtendsFruit<Apple>();
//Fruitํด๋ž˜์Šค์˜ ์ž์†๋“ค๋งŒ ๋‹ด์„ ์ˆ˜ ์žˆ๋‹ค๋Š” ์ œ์•ฝ์ด ์ถ”๊ฐ€๋˜์–ด Toy๋Š” ๋ชป๋‹ด์Œ
//FruitBox2<Toy> toyFruitBox = new FruitBox2<Toy>();

//์—ฌ์ „ํžˆ ์ƒ์†๊ด€๊ณ„์˜ ํƒ€์ž…๋“ค ๋‹ค ๊ฐ€๋Šฅํ•จ
FruitBoxExtendsFruit<Fruit> fruitBoxExtendsFruit = new FruitBoxExtendsFruit<Fruit>();
fruitBoxExtendsFruit.add(new Apple());
fruitBoxExtendsFruit.add(new Grape());

Fruit์™€ Eatable ์ธํ„ฐํŽ˜์ด์Šค ๊ตฌํ˜„

  • ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค๋Š” ์ œ์•ฝ์ด ์กด์žฌํ•œ๋‹ค๋ฉด

  • Eatable.interface

public interface Eatable {
}

/**
 * ์ธํ„ฐํŽ˜์ด์Šค๋„ ํƒ€์ž… ๋งค๊ฐœ๋ณ€์ˆ˜ T์— ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค
 * extends๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์— ์ฃผ์˜
 * Fruit์˜ ์ž์†์ด๋ฉด์„œ Eatable์ธํ„ฐํŽ˜์ด์Šค๋„ ๊ตฌํ˜„ํ•ด์•ผํ•œ๋‹ค๋ฉด ๋‹ค์Œ์ฒ˜๋Ÿผ & ๊ธฐํ˜ธ๋กœ ์—ฐ๊ฒฐํ•œ๋‹ค
 * @param <T>
 */
public class FruitBoxExtendsFruitandEatable<T extends Fruit & Eatable> extends Box {

    ArrayList<T> list = new ArrayList<T>();

}
  • Fruit์˜ ์ž์†์ด๋ฉด์„œ Eatable์„ ๊ตฌํ˜„ํ•œ ํด๋ž˜์Šค

public class FruitImplEatable extends Fruit implements Eatable{

    public String toString(){
        return "Fruit";
    }
}
  • main.java

//Fruit์˜ ์ž์†์ด๋ฉด์„œ Eatable์„ ๊ตฌํ˜„ํ•˜๋Š” FruitImplEatableํด๋ž˜์Šค๋ฅผ ํƒ€์ž…์œผ๋กœ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•˜๋‹ค
FruitBoxExtendsFruitandEatable<FruitImplEatable> fr = new FruitBoxExtendsFruitandEatable<FruitImplEatable>();

fr.add(new Apple());
fr.add(new Grape());

์™€์ผ๋“œ ์นด๋“œ

  • <? extends T> : ์™€์ผ๋“œ ์นด๋“œ์˜ ์ƒํ•œ ์ œํ•œ, T์™€ ๊ทธ ์ž์†๋“ค๋งŒ ๊ฐ€๋Šฅ

  • <? super T> : ์™€์ผ๋“œ ์นด๋“œ์˜ ํ•˜ํ•œ ์ œํ•œ, T์™€ ๊ทธ ์กฐ์ƒ๋“ค๋งŒ ๊ฐ€๋Šฅ

  • <?> : ์ œํ•œ ์—†์Œ ๋ชจ๋“  ํƒ€์ž…์ด ๊ฐ€๋Šฅํ•˜๋‹ค <? extends Object ์™€ ๋™์ผ

์™ธ์ผ๋“œ ์นด๋“œ์˜ ํ•„์š”์„ฑ

  • Juice.java

public class Juice {
    String name;

    Juice(String name) {
        this.name = name + "Juice";
    }
    public String toString(){ return name; }
}
  • Juicer.java

public class Juicer {

    /**
     * ์™€์ผ๋“œ ์นด๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด FruitBox<Fruit>๋ฟ๋งŒ ์•„๋‹ˆ๋ผ Fruit<Apple>๋“ฑ ์ž์†๋“ค๋„ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•˜๋‹ค.
     */
    static Juice makeJuice(FruitBox<? extends Fruit> box) {

        String tmp = "";
        for (Fruit f : box.getList()){
            tmp += f + " ";
        }
        return new Juice(tmp);
    }

    /**
     * ๋งค๊ฐœ๋ณ€์ˆ˜์— ๊ณผ์ผ๋ฐ•์Šค๋ฅผ ๋Œ€์ž…ํ•˜๋ฉด ์ฃผ์Šค๋ฅผ ๋งŒ๋“ค์–ด ๋ฐ˜ํ™˜ํ•˜๋Š” Juicerํด๋ž˜์Šค
     * ์ด ํด๋ž˜์Šค๋Š” ์ง€๋„ค๋ฆญํด๋ž˜์Šค๋„ ์•„๋‹ˆ๊ณ  static ์€ ํƒ€์ž… ๋งค๊ฐœ๋ณ€์ˆ˜ T๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค.
     * ๊ทธ๋ž˜์„œ Apple์„ ํƒ€์ž…์œผ๋กœํ•œ FruitBox๋ฅผ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋„ฃ์–ด์ฃผ๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒ..
     */
//    static Juice makeJuice(FruitBox<Fruit> box) {
//
//        String tmp = "";
//        for (Fruit f : box.getList()){
//            tmp += f + " ";
//        }
//        return new Juice(tmp);
//    }

    /**
     * Appleํƒ€์ž…์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ ์˜ค๋ฒ„๋กœ๋”ฉ ์ฝ”๋“œ๋ฅผ ์งœ๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
     * ์ง€๋„ค๋ฆญ ํƒ€์ž…์ด ๋‹ค๋ฅธ๊ฒƒ ๋งŒ์œผ๋กœ๋Š” ์˜ค๋ฒ„๋กœ๋”ฉ์ด ์„ฑ๋ฆฝํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
     * ์ง€๋„ค๋ฆญ ํƒ€์ž…์€ ์ปดํŒŒ์ผ ํ• ๋•Œ๋งŒ ์‚ฌ์šฉํ•˜๊ณ  ์ œ๊ฑฐํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๋Š” ๋ฉ”์„œ๋“œ ์ค‘๋ณต ์ •์˜๊ฐ€ ๋˜์–ด ์—๋Ÿฌ๊ฐ€ ๋‚œ๋‹ค.
     */
//    static Juice makeJuice(FruitBox<Apple> box) {
//
//        String tmp = "";
//        for (Fruit f : box.getList()){
//            tmp += f + " ";
//        }
//        return new Juice(tmp);
//    }
}
  • main.java

FruitBox<Fruit> fruit_FruitBox = new FruitBox<Fruit>();
FruitBox<Apple> apple_FruitBox = new FruitBox<Apple>();

//Fruit์™€ ๊ทธ ์ž์†์ธ Apple๋„ ๊ฐ€๋Šฅํ•จ
System.out.println("Juicer.makeJuice(fruit_FruitBox) = " + Juicer.makeJuice(fruit_FruitBox));
System.out.println("Juicer.makeJuice(apple_FruitBox) = " + Juicer.makeJuice(apple_FruitBox));

Collections.sort()๋ฅผ ์ด์šฉํ•œ ์ •๋ ฌ

  • Fruit

class Fruit {

    String name;
    int weight;

    Fruit(String name, int weight){
        this.name = name;
        this.weight = weight;
    }
    public String toString(){
        return name+"{"+weight+"}";
    }
}

public class FruitComp implements Comparator<Fruit> {

    public int compare(Fruit t1, Fruit t2){
        return t1.weight = t2.weight;
    }
}
  • Apple

class Apple extends Fruit {
    Apple(String name, int weight) {
        super(name, weight);
    }

    public String toString(){
        return name+"{"+weight+"}";
    }
}

public class AppleComp implements Comparator<Apple> {

    public int compare(Apple t1, Apple t2){
        return t2.weight - t1.weight;
    }
}
  • main.java

public class Main {
    public static void main(String[] args) {

        FruitBox<Apple> appleBox = new FruitBox<Apple>();

        appleBox.add(new Apple("GreenApple", 300));
        appleBox.add(new Apple("GreenApple", 100));
        appleBox.add(new Apple("GreenApple", 200));

        Collections.sort(appleBox.getList(), new AppleComp());
        System.out.println("appleBox = " + appleBox);

        Collections.sort(appleBox.getList(), new FruitComp());
        System.out.println("appleBox = " + appleBox);

    }
}

์ด๋Š” Collections.sort()๋ฅผ ์ด์šฉํ•ด appleBox์— ๋‹ด๊ธด ๊ณผ์ผ์„ ๋ฌด๊ฒŒ๋ณ„๋กœ ์ •๋ ฌํ•˜๋Š” ๊ฒƒ์ด๋‹ค. Collections์˜ ์„ ์–ธ๋ถ€๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค

static <T> void sort (List<T> list, Comparator<? super T> c)

์ด๋Š” ์ง€๋„ค๋ฆญ ๋ฉ”์„œ๋“œ์ด๋‹ค. list๋Š” ์ •๋ ฌํ•  ๋Œ€์ƒ, c๋Š” ์ •๋ ฌํ•  ๋ฐฉ๋ฒ•์ด ์ •์˜ ๋œ Comparator์ด๋‹ค. ์ง€๊ธˆ ์™€์ผ๋“œ ์นด๋“œ๊ฐ€ ์‚ฌ์šฉ๋˜์–ด new FruitComp๋กœ๋„ Apple์„ ์ •๋ ฌํ•  ์ˆ˜ ์žˆ๋‹ค. ๋งŒ์ผ ์™€์ผ๋“œ ์นด๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด Apple์€ Comparator<Apple>๋กœ Grape๋Š” Comparator<Grape>๋กœ๋งŒ ์ •๋ ฌํ•  ์ˆ˜ ์žˆ์„๊ฒƒ์ด๋‹ค. ์ƒˆ๋กœ์šด ๊ณผ์ผ์ด ์ƒ๊ธธ๋•Œ๋งˆ๋‹ค ~Comp.java๋ฅผ ๋งŒ๋“ค์–ด์ค„์ˆ˜๋Š” ์—†์œผ๋‹ˆ ์™€์ผ๋“œ์นด๋“œ๋กœ ํ•˜ํ•œ ์ œํ•œ์„ ํ•ด์ฃผ๋Š”๊ฒƒ์ด๋‹ค.

T์— Apple์ด ๋Œ€์ž…๋˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค

static <Apple> void sort (List<T> list, Comparator<? super Apple> c)

Comparator<? super Apple>์€ Comparator์˜ ํƒ€์ž… ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ Apple๊ณผ ๊ทธ ์กฐ์ƒ์ด ๊ฐ€๋Šฅํ•˜๋‹ค๋Š”๊ฑฐ๋‹ค. ๊ทธ๋ž˜์„œ new FruitComp๋กœ ๋‹ค๋ฅธ ๊ณผ์ผ๋“ค๋„ ์ •๋ ฌ๊ฐ€๋Šฅํ•˜๋‹ค.

๋ชฐ๋ก  ๊ณผ์ผ์˜ ์กฐ์ƒ์„ Fruit๋กœ ์ƒ์†ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

์ง€๋„ค๋ฆญ ๋ฉ”์„œ๋“œ

  • ๋ฉ”์„œ๋“œ ์„ ์–ธ๋ถ€์— ์ง€๋„ค๋ฆญ ํƒ€์ž…์ด ์„ ์–ธ๋œ ๋ฉ”์„œ๋“œ๋ฅผ ์ง€๋„ค๋ฆญ ๋ฉ”์„œ๋“œ๋ผ ํ•œ๋‹ค.

  • ์ง€๋„ค๋ฆญ ํด๋ž˜์Šค์— ์ •์˜๋œ ํƒ€์ž… ๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์ง€๋„ค๋ฆญ ๋ฉ”์„œ๋“œ์— ์ •์˜ ๋œ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ์ „ํ˜€ ๋ณ„๊ฐœ์˜ ๊ฒƒ์ด๋‹ค.

  • static ๋ฉค๋ฒ„์—๋Š” ํƒ€์ž… ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์ง€๋งŒ ๋ฉ”์„œ๋“œ์— ์ง€๋„ค๋ฆญ ํƒ€์ž…์„ ์„ ์–ธํ•˜๊ณ  ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ๊ฐ€๋Šฅํ•˜๋‹ค.

  • ์ด ํƒ€์ž… ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ๋ฉ”์„œ๋“œ ๋‚ด์—์„œ๋งŒ ์ง€์—ญ์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ง€์—ญ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•œ ๊ฒƒ๊ณผ ๊ฐ™๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋ฉด ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๋‹ค. ๊ทธ๋ ‡๊ธฐ์— static ์ด๋“  ์•„๋‹ˆ๋“  ์ƒ๊ด€์ด ์—†๋‹ค.

  • makeJuice๋ฅผ ์ง€๋„ค๋ฆญ ๋ฉ”์„œ๋“œ๋กœ ๋ฐ”๊พธ๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

 static <T extends Fruit>Juice makeJuice (FruitBox<T> box) {
	String tmp = "";
	for(Fruit f : box.getList()) {
		 tmp += f + " ";
	}
	return new Juice(tmp);
}
  • ์ด ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ๋• ์•„๋ž˜์™€ ๊ฐ™์ด ํƒ€์ž… ๋ณ€์ˆ˜์— ํƒ€์ž…์„ ๋Œ€์ž…ํ•ด์•ผ ํ•œ๋‹ค.

  • ํ•˜์ง€๋งŒ ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ํƒ€์ž…์„ ์ถ”์ •ํ•  ์ˆ˜ ์žˆ์–ด ์ƒ๋žตํ•ด๋„ ๋œ๋‹ค.

  • ํ•œ ๊ฐ€์ง€ ์ฃผ์˜ํ•  ์ ์€ ์ง€๋„ค๋ฆญ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ๋Œ€์ž…๋œ ํƒ€์ž…์„ ์ƒ๋žตํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ์—๋Š” ์ฐธ์กฐ๋ณ€์ˆ˜๋‚˜ ํด๋ž˜์Šค ์ด๋ฆ„์„ ์ƒ๋žตํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ๋‹จ์ง€ ๊ธฐ์ˆ ์ ์ธ ์ด์œ ์ด๋ฏ€๋กœ ์ง€์ผœ์•ผํ•œ๋‹ค.

FruitBox<Fruit> fruit_FruitBox = new FruitBox<Fruit>();
FruitBox<Apple> apple_FruitBox = new FruitBox<Apple>();

//Fruit์™€ ๊ทธ ์ž์†์ธ Apple๋„ ๊ฐ€๋Šฅํ•จ
System.out.println("Juicer.makeJuice(fruit_FruitBox) = " + Juicer.<Fruit>makeJuice(fruit_FruitBox));
System.out.println("Juicer.makeJuice(apple_FruitBox) = " + Juicer.<Apple>makeJuice(apple_FruitBox));
  • ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ํƒ€์ž…์ด ๋ณต์žกํ•  ๋•Œ ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•˜๋‹ค.

 static void printAll (ArrayList<? extends Product> list,
                       ArrayList<? extends Product> list2) {
    for (Unit u : list){
        System.out.println(u);
    }
}
//์œ„์˜ ์ฝ”๋“œ๋ฅผ ๊ฐ„๋žตํ•˜๊ฒŒ ๋ณ€๊ฒฝ
 static <T extends Product> void printAll (ArrayList<T> list,
                                           ArrayList<T> list2) {
    for (Unit u : list){
        System.out.println(u);
    }
}

์ง€๋„ค๋ฆญ ํƒ€์ž…์˜ ํ˜•๋ณ€ํ™˜

  • ์ง€๋„ค๋ฆญ ํƒ€์ž…๊ณผ ์ง€๋„ค๋ฆญ ํƒ€์ž…์ด ์•„๋‹Œ ํƒ€์ž…๊ฐ„์˜ ํ˜•๋ณ€ํ™˜์€ ํ•ญ์ƒ ๊ฐ€๋Šฅํ•˜๋‹ค.

  • ํ•˜์ง€๋งŒ ๋Œ€์ž…๋œ ํƒ€์ž…์ด ๋‹ค๋ฅธ ์ง€๋„ค๋ฆญ ํƒ€์ž… ๊ฐ„์—๋Š” ํ˜•๋ณ€ํ™˜์ด ๋ถˆ๊ฐ€ํ•˜๋‹ค.

Box<Object> objBox = null;
Box<String> strBox = null;

objBox = (Box<Object>) strBox; //์—๋Ÿฌ

//์ด๋ฏธ ์•„๋ž˜์™€ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์ƒ์„ฑ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ๊ฒƒ์„ ๋ฐฐ์› ๋‹ค ์ด๋Š” ์œ„์ฒ˜๋Ÿผ ํ˜•๋ณ€ํ™˜์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ๊ฒƒ์„ ๊ฐ„์ ‘์ ์œผ๋กœ ์•Œ๋ ค์ค€๋‹ค.
Box<Object> objBox = new Box<String>();

//ํ•˜์ง€๋งŒ ๋‹ค์Œ์˜ ๋ฌธ์žฅ์€ ํ˜•๋ณ€ํ™˜์ด ๊ฐ€๋Šฅํ•˜๋‹ค
Box<? extends Object> objBox = new Box<String>();
//๋ฐ˜๋Œ€์˜ ๊ฒฝ์šฐ๋Š” ์„ฑ๋ฆฝํ•˜์ง€๋งŒ ํ™•์ธ๋˜์ง€ ์•Š์€ ํ˜•๋ณ€ํ™˜์ด๋ผ๋Š” ๊ฒฝ๊ณ ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
FruitBox<? extends Fruit> box = null;
Box<Apple> appleBox = (FruitBox<Apple>) box;

Optional ํด๋ž˜์Šค

public final class Optional<T> {

    //EMPTY์— ๋น„์–ด์žˆ๋Š” Optional ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด์„œ ์ €์žฅ
    private static final Optional<?> EMPTY = new Optional<>();
    //<?> -> <? extends Object>๋ฅผ ์ค„์—ฌ์“ด๊ฒƒ
    //<>์•ˆ์— ์ƒ๋žต๋œ ํƒ€์ž…์€ <Object>์ด๋‹ค
    //๋”ฐ๋ผ์„œ ํ’€์–ด์“ฐ๋ฉด Optional<? extends Object> EMPTY = new Optional<Object>();
    private final T value;

    //EMPTY๋ฅผ ํ˜•๋ณ€ํ™˜ํ•ด์„œ ๋ฐ˜ํ™˜
    //EMPTY์˜ ํƒ€์ž…์„ Optional<Object>๊ฐ€ ์•„๋‹Œ Optional<?>๋กœ ํ•œ ์ด์œ ๋Š” Optional<T>๋กœ ํ˜•๋ณ€ํ™˜์ด ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๋งŒ์•ฝ Optional<Object>๋ฉด ํ˜•๋ณ€ํ™˜์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค. 
    public static<T> Optional<T> empty() {
        Optional<T> t = (Optional<T>) EMPTY;
        return t;
    }
}
  • ์ •๋ฆฌํ•˜๋ฉด Optional<Object>๋ฅผ Optional<String>์œผ๋กœ ์ง์ ‘ ํ˜•๋ณ€ํ™˜ ํ•˜๋Š”๊ฒƒ์€ ๋ถˆ๊ฐ€๋Šฅํ•˜์ง€๋งŒ ์™€์ผ๋“œ ์นด๋“œ๊ฐ€ ํฌํ•จ๋œ ์ง€๋„ค๋ฆญ ํƒ€์ž…์œผ๋กœ ํ˜•๋ณ€ํ™˜ ํ•˜๋ฉด ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

  • ์ฐธ๊ณ ๋กœ ์™€์ผ๋“œ ์นด๋“œ๊ฐ€ ์‚ฌ์šฉ๋œ ์ง€๋„ค๋ฆญ ํƒ€์ž…๋ผ๋ฆฌ๋„ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฝ์šฐ์— ํ˜•๋ณ€ํ™˜์ด ๊ฐ€๋Šฅํ•˜๋‹ค. ๋‹ค๋งŒ ๋ฏธํ™•์ • ํƒ€์ž…์œผ๋กœ ํ˜•๋ณ€ํ™˜ ํ•˜๋Š” ๊ฒƒ์ด๋ผ๋Š” ๊ฒฝ๊ณ ๊ฐ€ ๋œฌ๋‹ค.

FruitBox<? extends Object> objBox = null;
FruitBox<? extends String> strBox = null;

strBox = (FruitBox<? extends String>) objBox;
objBox = (FruitBox<? extends Object>) strBox;

์ง€๋„ค๋ฆญ ํƒ€์ž…์˜ ์ œ๊ฑฐ

  • ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์ง€๋„ค๋ฆญ ํƒ€์ž…์„ ์ด์šฉํ•ด ์†Œ์ŠคํŒŒ์ผ์„ ์ฒดํฌ ํ•œ๋’ค ํ•„์š”ํ•œ ๊ณณ์— ํ˜•๋ณ€ํ™˜์„ ๋„ฃ์–ด์ค€๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ง€๋„ค๋ฆญ ํƒ€์ž…์„ ์ œ๊ฑฐํ•œ๋‹ค.

  • ์ฆ‰ ์ปดํŒŒ์ผ๋œ .class ํŒŒ์ผ์—๋Š” ์ง€๋„ค๋ฆญ ํƒ€์ž…์— ๋Œ€ํ•œ ์ •๋ณด๊ฐ€ ์—†๋‹ค.

  • ๊ทธ ์ด์œ ๋Š” ์ง€๋„ค๋ฆญ์ด ๋„์ž…๋˜๊ธฐ ์ด์ „์˜ ์†Œ์Šค์ฝ”๋“œ์™€์˜ ํ˜ธํ™˜์„ฑ์„ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด์„œ์ด๋‹ค.

  • ์ง€๋„ค๋ฆญ ํƒ€์ž…์˜ ์ œ๊ฑฐ ๊ณผ์ •์€ ๊ฝค ๋ณต์žกํ•˜๋‹ค. ๊ธฐ๋ณธ์ ์ธ ์ œ๊ฑฐ ๊ณผ์ •๋งŒ ์•Œ์•„๋ณด์ž.

  1. ์ง€๋„ค๋ฆญ ํƒ€์ž…์˜ ๊ฒฝ๊ฒŒ๋ฅผ ์ œ๊ฑฐํ•œ๋‹ค. ์ง€๋„ค๋ฆญ ํƒ€์ž…์ด <T extends Fruit> ๋ผ๋ฉด T๋Š” Fruit๋กœ ์น˜ํ™˜๋˜๊ณ  <T>์ธ ๊ฒฝ์šฐ๋Š” Object๋กœ ์น˜ํ™˜๋œ๋‹ค. ํด๋ž˜์Šค์˜†์˜ ์„ ์–ธ์€ ์ œ๊ฑฐ๋œ๋‹ค.

  2. ์ง€๋„ค๋ฆญ ํƒ€์ž…์„ ์ œ๊ฑฐํ•œ ํ›„์— ํƒ€์ž…์ด ์ผ์น˜ํ•˜์ง€ ์•Š์œผ๋ฉด ํ˜•๋ณ€ํ™˜์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

 static Juice makeJuice (FruitBox<? extends Fruit> box) {
	String tmp = "";
	for(Fruit f : box.getList()) {
		 tmp += f + " ";
	}
	return new Juice(tmp);
}
  • ์œ„์™€๊ฐ™์ด ์™€์ผ๋“œ ์นด๋“œ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ๋Š” ๊ฒฝ์šฐ์— ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ ์ ˆํ•œ ํƒ€์ž…์œผ๋กœ์˜ ํ˜•๋ณ€ํ™˜์ด ์ถ”๊ฐ€๋œ๋‹ค.

 static Juice makeJuice (FruitBox box) {
	String tmp = "";
	Iterator it = box.getList().iterator();
	while(it.hasNext()) {
		 tmp += (Fruit)it.next() + " ";
	}
	return new Juice(tmp);
}

Last updated