β μλ° μ λ€λ¦(Generics) κ°λ & λ¬Έλ² μ 볡νκΈ°
μ λ€λ¦ (Generics) μ΄λ
μλ°μμ μ λ€λ¦(Generics)μ ν΄λμ€ λ΄λΆμμ μ¬μ©ν λ°μ΄ν° νμ μ μΈλΆμμ μ§μ νλ κΈ°λ²μ μλ―Ένλ€. κ°μ²΄λ³λ‘ λ€λ₯Έ νμ μ μλ£κ° μ μ₯λ μ μλλ‘ νλ€.
μλ°μμ λ°°μ΄κ³Ό ν¨κ» μμ£Ό μ°μ΄λ μλ£νμ΄ λ¦¬μ€νΈ(List)μΈλ°, λ€μκ³Ό κ°μ΄ ν΄λμ€ μ μΈ λ¬Έλ²μ κΊΎμ κ΄νΈ <> λ‘ λμ΄μλ μ½λ ννλ₯Ό νλ² μ―€μ λ΄€μ κ²μ΄λ€.
ArrayList<String> list = new ArrayList<>();
μ κΊΎμ κ΄νΈκ° λ°λ‘ μ λ€λ¦μ΄λ€. κ΄νΈ μμλ νμ λͺ μ κΈ°μ¬νλ€. κ·Έλ¬λ©΄ μ 리μ€νΈ ν΄λμ€ μλ£νμ νμ μ String νμ μΌλ‘ μ§μ λμ΄ λ¬Έμμ΄ λ°μ΄ν°λ§ 리μ€νΈμ μ μ¬ν μ μκ² λλ€.
μλ κ·Έλ¦Όκ³Ό κ°μ΄ λ°°μ΄κ³Ό 리μ€νΈμ μ μΈλ¬Έ ννλ₯Ό λΉκ΅ν΄λ³΄λ©΄ μ΄ν΄νκΈ° μ¬μΈ κ²μ΄λ€. μ μΈνλ ν€μλλ λ¬Έλ² μμκ° λ€λ₯ΌλΏ, κ²°κ΅ μλ£νλͺ μ μ μΈνκ³ μλ£νμ νμ μ μ§μ νλ€λ μ μ κ°λ€κ³ λ³Ό μ μλ€.
μ΄μ²λΌ μ λ€λ¦μ λ°°μ΄μ νμ μ μ§μ νλ―μ΄ λ¦¬μ€νΈ μλ£ν κ°μ 컬λ μ ν΄λμ€λ λ©μλμμ μ¬μ©ν λ΄λΆ λ°μ΄ν° νμ (type)μ νλΌλ―Έν°(parameter) μ£Όλ―μ΄ μΈλΆμμ μ§μ νλ μ΄λ₯Έλ° νμ μ λ³μν ν κΈ°λ₯μ΄λΌκ³ μ΄ν΄νλ©΄ λλ€.
μ°λ¦¬κ° λ³μλ₯Ό μ μΈν λ λ³μμ νμ μ μ§μ ν΄μ£Όλ―μ΄, μ λ€λ¦μ κ°μ²΄(Object)μ νμ μ μ§μ ν΄μ£Όλ κ²μ΄λΌκ³ 보면 λλ€.
μ λ€λ¦ νμ 맀κ°λ³μ
μμμ 보λ€μνΌ, μ λ€λ¦μ <> κΊΎμ κ΄νΈ ν€μλλ₯Ό μ¬μ©νλλ° μ΄λ₯Ό λ€μ΄μλͺ¬λ μ°μ°μλΌκ³ νλ€. κ·Έλ¦¬κ³ μ΄ κΊΎμ κ΄νΈ μμ μλ³μ κΈ°νΈλ₯Ό μ§μ ν¨μΌλ‘μ¨ νλΌλ―Έν°ν ν μ μλ€. μ΄κ²μ λ§μΉ λ©μλκ° λ§€κ°λ³μλ₯Ό λ°μ μ¬μ©νλ κ²κ³Ό λΉμ·νμ¬ μ λ€λ¦μ νμ
맀κ°λ³μ(parameter) / νμ
λ³μ λΌκ³ λΆλ₯Έλ€.
νμ νλΌλ―Έν° μ μ
μ΄ νμ 맀κ°λ³μλ μ λ€λ¦μ μ΄μ©ν ν΄λμ€λ λ©μλλ₯Ό μ€κ³ν λ μ¬μ©λλ€.
μλ₯Όλ€μ΄ λ€μ μ½λλ μ λ€λ¦μ κ°λ―Έν ν΄λμ€λ₯Ό μ μν μ½λμ΄λ€. ν΄λμ€λͺ
μμ <T> κΈ°νΈλ‘ μ λ€λ¦μ λΆμ¬μ€ κ±Έ λ³Ό μ μλ€. κ·Έλ¦¬κ³ ν΄λμ€ λ΄λΆμμ μλ³μ κΈ°νΈ T λ₯Ό ν΄λμ€ νλμ, λ©μλμ 맀κ°λ³μμ νμ
μΌλ‘ μ§μ λμ΄ μλ€.
class FruitBox<T> {
List<T> fruits = new ArrayList<>();
public void add(T fruit) {
fruits.add(fruit);
}
}
μ λ€λ¦ ν΄λμ€λ₯Ό λ§λ€μμΌλ©΄ μ΄λ₯Ό μΈμ€ν΄μ€ν ν΄λ³΄μ. λ§μΉ νλΌλ―Έν°λ₯Ό μ§μ ν΄μ 보λ΄λ κ² μ²λΌ μμ± μ½λμμ κΊΎμ κ΄νΈ μμ μ§μ ν΄μ£Όκ³ μΆμ νμ
λͺ
μ ν λΉν΄μ£Όλ©΄, μ λ€λ¦ ν΄λμ€ μ μΈλ¬Έ λΆλΆμΌλ‘ κ°μ νμ
νλΌλ―Έν° T κ° μ§μ λ νμ
μΌλ‘ λͺ¨λ λ³νλμ΄ ν΄λμ€μ νμ
μ΄ μ§μ λκ² λλ κ²μ΄λ€.
// μ λ€λ¦ νμ
맀κ°λ³μμ μ μ νμ
μ ν λΉ
FruitBox<Integer> intBox = new FruitBox<>();
// μ λ€λ¦ νμ
맀κ°λ³μμ μ€μ νμ
μ ν λΉ
FruitBox<Double> intBox = new FruitBox<>();
// μ λ€λ¦ νμ
맀κ°λ³μμ λ¬Έμμ΄ νμ
μ ν λΉ
FruitBox<String> intBox = new FruitBox<>();
// ν΄λμ€λ λ£μ΄μ€ μ μλ€. (Apple ν΄λμ€κ° μλ€κ³ κ°μ )
FruitBox<Apple> intBox = new FruitBox<Apple>();
μ΄λ₯Ό κ·Έλ¦ΌμΌλ‘ ννν΄λ³΄λ©΄, λ€μκ³Ό κ°μ΄ μ λ€λ¦ νμ
μ νκ° νν΄μ§κ³ 보면 λλ€. <T> λΆλΆμμ μ€νλΆμμ νμ
μ λ°μμ λ΄λΆμμ T νμ
μΌλ‘ μ§μ ν λ©€λ²λ€μκ² μ ννμ¬ νμ
μ΄ κ΅¬μ²΄μ μΌλ‘ μ€μ λλ κ²μ΄λ€. μ΄λ₯Ό μ λ¬Έ μ©μ΄λ‘ ꡬ체ν(Specialization) λΌκ³ νλ€.
νμ νλΌλ―Έν° μλ΅
μ λ€λ¦ κ°μ²΄λ₯Ό μ¬μ©νλ λ¬Έλ² ννλ₯Ό 보면 μμͺ½ λ κ΅°λ°μ κΊΎμ κ΄νΈ μ λ€λ¦ νμ μ μ§μ ν¨μ λ³Ό μ μλ€. νμ§λ§ 맨 μμμ ν΄λμ€λͺ κ³Ό ν¨κ» νμ μ μ§μ ν΄ μ£Όμλλ° κ΅³μ΄ μμ±μκΉμ§ μ λ€λ¦μ μ§μ ν΄ μ€ νμκ° μλ€. (μ€λ³΅)
λ°λΌμ jdk 1.7 λ²μ μ΄νλΆν°, new μμ±μ λΆλΆμ μ λ€λ¦ νμ μ μλ΅ν μ μκ² λμλ€. μ λ€λ¦ λλ¦λλ‘ νμ μΆλ‘ μ ν΄μ μλ΅ λ κ³³μ λ£μ΄μ£ΌκΈ° λλ¬Έμ λ¬Έμ κ° μλ κ²μ΄λ€.
FruitBox<Apple> intBox = new FruitBox<Apple>();
// λ€μκ³Ό κ°μ΄ new μμ±μ λΆλΆμ μ λ€λ¦μ νμ
맀κ°λ³μλ μλ΅ν μ μλ€.
FruitBox<Apple> intBox = new FruitBox<>();
νμ νλΌλ―Έν° ν λΉ κ°λ₯ νμ
μ λ€λ¦μμ ν λΉ λ°μ μ μλ νμ μ Reference νμ λΏμ΄λ€. μ¦, intν μ΄λ doubleν κ°μ μλ° μμ νμ (Primitive Type)μ μ λ€λ¦ νμ νλΌλ―Έν°λ‘ λκΈΈ μ μλ€λ λ§μ΄λ€.
μ°λ¦¬κ° Wrapper ν΄λμ€μ λν΄ κ³΅λΆν λ intν, doubleνμ΄ μ΄λ―Έ μ‘΄μ¬νλλ°, μ κ΅³μ΄ λκ°μ μν μ νλ Integerν, Doubleν ν΄λμ€λ₯Ό λ§λ€μ΄λ¨μκΉ κ³ λ―Όμ ν΄λ³Έμ μ΄ μμμ κ²μ΄λ€. λ°λ‘ μ΄λ μ¬μ©νλ κ²μ΄λΌκ³ μ΄ν΄νλ©΄ λλ€.
λ°λ‘ μ μμ΄ λμ§λ μκ² μ§λ§, κ°μ²΄ μ§ν₯ νλ‘κ·Έλλ°μμλ λͺ¨λ κ²μ΄ κ°μ²΄λ‘ ν΅μ νκΈ° λλ¬Έμ λ²κ±°λ‘λλΌλ μ΅μν΄ μ§μ΄μΌ νλ€.
// κΈ°λ³Έ νμ
intλ μ¬μ© λΆκ° !!!
List<int> intList = new List<>();
// Wrapper ν΄λμ€λ‘ λ겨주μ΄μΌ νλ€. (λ΄λΆμμ μλμΌλ‘ μΈλ°μ±λμ΄ μμ νμ
μΌλ‘ μ΄μ©λ¨)
List<Integer> integerList = new List<>();
λν μ λ€λ¦ νμ νλΌλ―Έν°μ ν΄λμ€κ° νμ μΌλ‘ μ¨λ€λ κ²μ, ν΄λμ€λΌλ¦¬ μμμ ν΅ν΄ κ΄κ³λ₯Ό λ§Ίλ κ°μ²΄ μ§ν₯ νλ‘κ·Έλλ°μ λ€νμ± μλ¦¬κ° κ·Έλλ‘ μ μ©μ΄ λλ€λ μ리μ΄λ€.
μλ μμ μ½λλ₯Ό 보면 νμ
νλΌλ―Έν°λ‘ <Fruit> λ‘ μ§μ νμ§λ§ μ
μΊμ€ν
μ ν΅ν΄ κ·Έ μμ κ°μ²΄λ ν λΉμ΄ λ¨μ λ³Ό μ μλ€.
class Fruit { }
class Apple extends Fruit { }
class Banana extends Fruit { }
class FruitBox<T> {
List<T> fruits = new ArrayList<>();
public void add(T fruit) {
fruits.add(fruit);
}
}
public class Main {
public static void main(String[] args) {
FruitBox<Fruit> box = new FruitBox<>();
// μ λ€λ¦ νμ
μ λ€νμ± μλ¦¬κ° κ·Έλλ‘ μ μ©λλ€.
box.add(new Fruit());
box.add(new Apple());
box.add(new Banana());
}
}
볡μ νμ νλΌλ―Έν°
μ λ€λ¦μ λ°λμ νκ°λ§ μ¬μ©νλΌλ λ²μ μλ€. λ§μΌ νμ μ§μ μ΄ μ¬λ¬κ°κ° νμν κ²½μ° 2κ°, 3κ° μΌλ§λ μ§ λ§λ€ μ μλ€.
μ λ€λ¦ νμ
μ ꡬλΆμ κΊ½μ κ΄νΈ μμμ μ½ν(,)λ‘ νλ©° <T, U> μ κ°μ νμμ ν΅ν΄ 볡μ νμ
νλΌλ―Έν°λ₯Ό μ§μ ν μ μλ€. κ·Έλ¦¬κ³ λΉμ°ν ν΄λμ€ μ΄κΈ°νν λ μ λ€λ¦ νμ
μ λκ°λ₯Ό λ겨주μ΄μΌ νλ€.
import java.util.ArrayList;
import java.util.List;
class Apple {}
class Banana {}
class FruitBox<T, U> {
List<T> apples = new ArrayList<>();
List<U> bananas = new ArrayList<>();
public void add(T apple, U banana) {
apples.add(apple);
bananas.add(banana);
}
}
public class Main {
public static void main(String[] args) {
// 볡μ μ λ€λ¦ νμ
FruitBox<Apple, Banana> box = new FruitBox<>();
box.add(new Apple(), new Banana());
box.add(new Apple(), new Banana());
}
}
μ€μ²© νμ νλΌλ―Έν°
μ λ€λ¦ κ°μ²΄λ₯Ό μ λ€λ¦ νμ νλΌλ―Έν°λ‘ λ°λ νμλ ννν μ μλ€.
ArrayList μ체λ νλμ νμ μΌλ‘μ¨ μ λ€λ¦ νμ νλΌλ―Έν°κ° λ μ μκΈ° λλ¬Έμ μ΄λ κ² μ€μ²© νμμΌλ‘ μ¬μ©ν μ μλ κ²μ΄λ€.
public static void main(String[] args) {
// LinkedList<String>μ μμλ‘μ μ μ₯νλ ArrayList
ArrayList<LinkedList<String>> list = new ArrayList<LinkedList<String>>();
LinkedList<String> node1 = new LinkedList<>();
node1.add("aa");
node1.add("bb");
LinkedList<String> node2 = new LinkedList<>();
node2.add("11");
node2.add("22");
list.add(node1);
list.add(node2);
System.out.println(list);
}
νμ νλΌλ―Έν° κΈ°νΈ λ€μ΄λ°
μ§κΈκΉμ§ μ λ€λ¦ κΈ°νΈλ₯Ό <T> μ κ°μ΄ μ¨μ νννμ§λ§ μ¬μ€ μλ³μ κΈ°νΈλ λ¬Έλ²μ μΌλ‘ μ ν΄μ§ κ²μ΄ μλ€.
λ€λ§ μ°λ¦¬κ° forλ¬Έμ μ΄μ©ν λ 루ν λ³μλ₯Ό i λ‘ μ§μ ν΄μ μ¬μ©νλ―μ΄, μ λ€λ¦μ νν λ³μλ₯Ό T λ‘ νννλ€κ³ 보면 λλ€. λ§μΌ λλ²μ§Έ, μΈλ²μ§Έ μ λ€λ¦μ΄ νμνλ€κ³ 보면 forλ¬Έμ jλ k κ°μ΄ S, U λ‘ μ΄μ΄λκ°λ€.
λͺ
λͺ
νκ³ μΆμλλ‘ μ무 λ¨μ΄λ λ£μ΄λ λ¬Έμ λ μμ§λ§, λμ€μ μΌλ‘ ν΅νλ ν΅μμ μΈ λ€μ΄λ°μ΄ μμΌλ©΄ κ°λ°μ΄ μ©μ΄ν΄ μ§κΈ° λλ¬Έμ μλ νν κ°μ μ묡μ μΈ κ·μΉ(convention)μ΄ μ‘΄μ¬νλ€. μλ₯Όλ€μ΄ μμ μμ μ¬μ©λ T λ₯Ό νμ
λ³μ(type variable)λΌκ³ νλ©°, μμμ μ°Έμ‘°ν νμ
μ μλ―Ένλ€.
νμ | μ€λͺ |
<T> | νμ (Type) |
<E> | μμ(Element), μλ₯Ό λ€μ΄ List |
<K> | ν€(Key), μλ₯Ό λ€μ΄ Map<k, v> |
<V> | λ¦¬ν΄ κ° λλ 맀νλ κ°(Variable) |
<N> | μ«μ(Number) |
<S, U, V> | 2λ²μ§Έ, 3λ²μ§Έ, 4λ²μ§Έμ μ μΈλ νμ |
μ λ€λ¦ μ¬μ© μ΄μ μ μ΄μ
1. μ»΄νμΌ νμμ νμ κ²μ¬λ₯Ό ν΅ν΄ μμΈ λ°©μ§
μλ°μμ μ λ€λ¦(Generic)μ μλ° 1.5μ μΆκ°λ μ€νμ΄λ€. κ·Έλμ JDK 1.5 μ΄μ μμλ μ¬λ¬ νμ μ λ€λ£¨κΈ° μν΄ μΈμλ λ°νκ°μΌλ‘ Object νμ μ μ¬μ©νμμλ€. νμ§λ§ Objectλ‘ νμ μ μ μΈν κ²½μ° λ°νλ Object κ°μ²΄λ₯Ό λ€μ μνλ νμ μΌλ‘ μΌμΌν νμ λ³νμ ν΄μΌ νλ©°, λ°νμ μλ¬κ° λ°μν κ°λ₯μ±λ μ‘΄μ¬νκ² λλ€.
μλ μμ μμ Object νμ μΌλ‘ μ μΈν λ°°μ΄μ Apple κ³Ό Banana κ°μ²΄ νμ μ μ μ₯νκ³ μ΄λ₯Ό λ€μ κ°μ Έμ€λ μμ μ΄λ€.
class Apple {}
class Banana {}
class FruitBox {
// λͺ¨λ ν΄λμ€ νμ
μ λ°κΈ° μν΄ μ΅κ³ μ‘°μμΈ Object νμ
μΌλ‘ μ€μ
private Object[] fruit;
public FruitBox(Object[] fruit) {
this.fruit = fruit;
}
public Object getFruit(int index) {
return fruit[index];
}
}
public static void main(String[] args) {
Apple[] arr = {
new Apple(),
new Apple()
};
FruitBox box = new FruitBox(arr);
Apple apple = (Apple) box.getFruit(0);
Banana banana = (Banana) box.getFruit(1);
}
κ·Έλ°λ° μ€νν΄λ³΄λ©΄ μμ κ°μ΄ ClassCastException λ°νμ μλ¬κ° λ°μνκ² λλ€. κ°μ²΄λ₯Ό κ°μ Έμ¬λ νλ³νλ μ ν΄μ£Όμ΄ λ¬Έμ κ° μλ κ² κ°μλ° λ¬΄μμ΄ λ¬Έμ μΌκΉ?
μμΈμ κ°λ¨νλ€. Apple κ°μ²΄ νμ μ λ°°μ΄μ FruitBoxμ λ£μλλ°, κ°λ°μκ° μ°©κ°νκ³ Bananaλ₯Ό νλ³ννμ¬ κ°μ Έμ€λ €κ³ νμκΈ° λλ¬Έμ μκΈ΄ νμμ΄λ€. 미리 μ½λμμ λΉ¨κ°μ€λ‘ μλ €μ€¬μΌλ©΄ μ’κ² μ§λ§ 보λ€μνΌ κΉ¨λνλ€.
μ λ€λ¦μ μ΄μ©νλ©΄ μ΄λ° μ΄μ²κ΅¬λ μλ μ€μλ₯Ό λ―Έμ°μ λ°©μ§λ₯Ό ν μ μλ€. μλνλ©΄ μ½λλ₯Ό μ€ννκΈ°μ μ»΄νμΌ νμμ 미리 μλ¬λ₯Ό μ°Ύμ μλ €μ£ΌκΈ° λλ¬Έμ΄λ€.
class FruitBox<T> {
private T[] fruit;
public FruitBox(T[] fruit) {
this.fruit = fruit;
}
public T getFruit(int index) {
return fruit[index];
}
}
public static void main(String[] args) {
Apple[] arr = {
new Apple(),
new Apple()
};
FruitBox<Apple> box = new FruitBox<>(arr);
Apple apple = (Apple) box.getFruit(0);
Banana banana = (Banana) box.getFruit(1);
}
μ΄ μ²λΌ μ λ€λ¦μ ν΄λμ€λ λ©μλλ₯Ό μ μν λ νμ νλΌλ―Έν°λ‘ κ°μ²΄μ μλΈ νμ μ μ§μ ν΄μ€μΌλ‘μ¨, μλͺ»λ νμ μ΄ μ¬μ©λ μ μλ λ¬Έμ λ₯Ό μ»΄νμΌ κ³Όμ μμ μ κ±°νμ¬ κ°λ°μ μ©μ΄νκ² ν΄μ€λ€.
2. λΆνμν μΊμ€ν μ μμ μ±λ₯ ν₯μ
μμ μμ μ½λμμ Apple λ°°μ΄μ FruitBoxμ Object λ°°μ΄ κ°μ²΄μ λ£κ³ , λ°°μ΄ μμλ₯Ό κ°μ Έμ¬λ λ°λμ λ€μ΄ μΊμ€ν (down casting)μ ν΅ν΄ κ°μ ΈμμΌ νλ€. μ΄λ 곧 μΆκ°μ μΈ μ€λ²ν€λκ° λ°μνλ κ²κ³Ό κ°λ€.
Apple[] arr = { new Apple(), new Apple(), new Apple() };
FruitBox box = new FruitBox(arr);
// κ°μ Έμ¨ νμ
μ΄ Object νμ
μ΄κΈ° λλ¬Έμ μΌμΌν λ€μ΄μΊμ€ν
μ ν΄μΌν¨ - μΈλ°μλ μ±λ₯ λλΉ
Apple apple1 = (Apple) box.getFruit(0);
Apple apple2 = (Apple) box.getFruit(1);
Apple apple3 = (Apple) box.getFruit(2);
λ°λ©΄ μ λ€λ¦μ 미리 νμ μ μ§μ & μ νν΄ λκΈ° λλ¬Έμ ν λ³ν(Type Casting)μ λ²κ±°λ‘μμ μ€μΌ μ μμΌλ©°, νμ κ²μ¬μ λ€μ΄κ°λ λ©λͺ¨λ¦¬λ₯Ό μ€μΌ μ μκ³ λλΆμ΄ κ°λ μ±λ μ’μμ§λ€.
// 미리 μ λ€λ¦ νμ
νλΌλ―Έν°λ₯Ό ν΅ν΄ ν(type)μ μ§μ ν΄λμκΈ° λλ¬Έμ λ³λμ νλ³νμ νμμλ€.
FruitBox<Apple> box = new FruitBox<>(arr);
Apple apple = box.getFruit(0);
Apple apple = box.getFruit(1);
Apple apple = box.getFruit(2);
μ λ€λ¦ μ¬μ© μ£Όμμ¬ν
1. μ λ€λ¦ νμ μ κ°μ²΄λ μμ±μ΄ λΆκ°
μ λ€λ¦ νμ
μμ²΄λ‘ νμ
μ μ§μ νμ¬ κ°μ²΄λ₯Ό μμ±νλ κ²μ λΆκ°λ₯ νλ€. μ¦, new μ°μ°μ λ€μ μ λ€λ¦ νμ
νλΌλ―Έν°κ° μ¬μλ μλ€.
class Sample<T> {
public void someMethod() {
// Type parameter 'T' cannot be instantiated directly
T t = new T();
}
}
2. static λ©€λ²μ μ λ€λ¦ νμ μ΄ μ¬μ μμ
μλ μ²λΌ static λ³μμ λ°μ΄ν° νμ μΌλ‘ μ λ€λ¦ νμ νλΌλ―Έν°κ° μ¬μλ μλ€. μλνλ©΄ static λ©€λ²λ ν΄λμ€κ° λμΌνκ² κ³΅μ νλ λ³μλ‘μ μ λ€λ¦ κ°μ²΄κ° μμ±λκΈ°λ μ μ μ΄λ―Έ μλ£ νμ μ΄ μ ν΄μ Έ μμ΄μΌ νκΈ° λλ¬Έμ΄λ€. μ¦, λ Όλ¦¬μ μΈ μ€λ₯μΈ κ²μ΄λ€.
class Student<T> {
private String name;
private int age = 0;
// static λ©μλμ λ°ν νμ
μΌλ‘ μ¬μ© λΆκ°
public static T addAge(int n) {
}
}
class Student<T> {
private String name;
private int age = 0;
// static λ©μλμ 맀κ°λ³μ νμ
μΌλ‘ μ¬μ© λΆκ°
public static void addAge(T n) {
}
}
3. μ λ€λ¦μΌλ‘ λ°°μ΄ μ μΈ μ£Όμμ
κΈ°λ³Έμ μΌλ‘ μ λ€λ¦ ν΄λμ€ μ체λ₯Ό λ°°μ΄λ‘ λ§λ€ μλ μλ€.
class Sample<T> {
}
public class Main {
public static void main(String[] args) {
Sample<Integer>[] arr1 = new Sample<>[10];
}
}
νμ§λ§ μ λ€λ¦ νμ μ λ°°μ΄ μ μΈμ νμ©λλ€.
μμ μκ³Ό μ°¨μ΄μ μ λ°°μ΄μ μ μ₯ν Sample κ°μ²΄μ νμ
νλΌλ―Έν°λ₯Ό Integer λ‘ μ§μ νλ€λ λ»μ΄λ€. μ¦, new Sample<Integer>() μΈμ€ν΄μ€λ μ μ₯μ΄ κ°λ₯νλ©°, new Sample<String>() μΈμ€ν΄μ€λ μ μ₯μ΄ λΆκ°λ₯νλ€λ μ리μ΄λ€.
class Sample<T> {
}
public class Main {
public static void main(String[] args) {
// new Sample<Integer>() μΈμ€ν΄μ€λ§ μ μ₯νλ λ°°μ΄μ λνλ
Sample<Integer>[] arr2 = new Sample[10];
// μ λ€λ¦ νμ
μ μλ΅ν΄λ μμμ μ΄λ―Έ μ μνκΈ° λλ¬Έμ Integer κ° μλμΌλ‘ μΆλ‘ λ¨
arr2[0] = new Sample<Integer>();
arr2[1] = new Sample<>();
// ! Integerκ° μλ νμ
μ μ μ₯ λΆκ°λ₯
arr2[2] = new Sample<String>();
}
}
μ λ€λ¦ κ°μ²΄ λ§λ€μ΄λ³΄κΈ°
μ λ€λ¦μ μ΄μ©ν΄ μ§μ ν΄λμ€μ μΈν°νμ΄μ€, λ©μλλ₯Ό λ§λ€μ΄λ³΄κ³ μ¬μ©ν΄λ³΄λ μκ°μ κ°μ Έλ³΄μ.
μ λ€λ¦ ν΄λμ€
ν΄λμ€ μ μΈλ¬Έ μμ μ λ€λ¦ νμ 맀κ°λ³μκ° μ°μ΄λ©΄, μ΄λ₯Ό μ λ€λ¦ ν΄λμ€λΌκ³ νλ€.
class Sample<T> {
private T value; // λ©€λ² λ³μ valμ νμ
μ T μ΄λ€.
// T νμ
μ κ° valμ λ°ννλ€.
public T getValue() {
return value;
}
// T νμ
μ κ°μ λ©€λ² λ³μ valμ λμ
νλ€.
public void setValue(T value) {
this.value = value;
}
}
public static void main(String[] args) {
// μ μνμ λ€λ£¨λ μ λ€λ¦ ν΄λμ€
Sample<Integer> s1 = new Sample<>();
s1.setValue(1);
// μ€μνμ λ€λ£¨λ μ λ€λ¦ ν΄λμ€
Sample<Double> s2 = new Sample<>();
s2.setValue(1.0);
// λ¬Έμμ΄μ λ€λ£¨λ μ λ€λ¦ ν΄λμ€
Sample<String> s3 = new Sample<>();
s3.setValue("1");
}
μ λ€λ¦ μΈν°νμ΄μ€
μΈν°νμ΄μ€μλ μ λ€λ¦μ μ μ© ν μ μλ€. λ¨, μΈν°νμ΄μ€λ₯Ό implements ν ν΄λμ€μμλ μ€λ²λΌμ΄λ©ν λ©μλλ₯Ό μ λ€λ¦ νμ
μ λ§μΆ°μ λκ°μ΄ ꡬνν΄ μ£Όμ΄μΌ νλ€.
interface ISample<T> {
public void addElement(T t, int index);
public T getElement(int index);
}
class Sample<T> implements ISample<T> {
private T[] array;
public Sample() {
array = (T[]) new Object[10];
}
@Override
public void addElement(T element, int index) {
array[index] = element;
}
@Override
public T getElement(int index) {
return array[index];
}
}
public static void main(String[] args) {
Sample<String> sample = new Sample<>();
sample.addElement("This is string", 5);
sample.getElement(5);
}
μ λ€λ¦ ν¨μν μΈν°νμ΄μ€
νΉν μ λ€λ¦ μΈν°νμ΄μ€κ° μ λ§ λ§μ΄ μ¬μ©λλ κ³³μ΄ λ°λ‘ λλ€ ννμμ ν¨μν μΈν°νμ΄μ€μ΄λ€. μμ§ μλ°μ λλ€μμ λν΄ λ°°μ°μ§ μμ λ μλΆλ€λ κ³μκ² μ§λ§, μμΌλ‘ λ°°μΈ μμ μΌ κ²μ΄λ λλ€ ν¨μμ μ λ€λ¦μ μμ© ννλ₯Ό λμ μ΅νκ³ κ°λκ²μ μΆμ²νλ λ°λ€.
// μ λ€λ¦μΌλ‘ νμ
μ λ°μ, ν΄λΉ νμ
μ λ κ°μ λνλ μΈν°νμ΄μ€
interface IAdd<T> {
public T add(T x, T y);
}
public class Main {
public static void main(String[] args) {
// μ λ€λ¦μ ν΅ν΄ λλ€ ν¨μμ νμ
μ κ²°μ
IAdd<Integer> o = (x, y) -> x + y; // 맀κ°λ³μ xμ y κ·Έλ¦¬κ³ λ°νν νμ
μ΄ intνμΌλ‘ μ€μ λλ€.
int result = o.add(10, 20);
System.out.println(result); // 30
}
}
μ λ€λ¦ λ©μλ
μ λ€λ¦ λ©μλ λΆλΆμ μ λ€λ¦ ν΄λμ€, μΈν°νμ΄μ€μ λ¬λ¦¬ λμ΄λκ° μ‘°κΈ μλ€.
μλμ κ°μ΄ μ λ€λ¦ ν΄λμ€μμ μ λ€λ¦ νμ νλΌλ―Έν°λ₯Ό μ¬μ©νλ λ©μλλ₯Ό μ λ€λ¦ λ©μλλΌκ³ μ°©κ°νκΈ° μ¬μ΄λ°, μ΄κ²μ κ·Έλ₯ νμ νλΌλ―Έν°λ‘ νμ μ μ§μ ν λ©μλ μΌ λΏμ΄λ€.
class FruitBox<T> {
public T addBox(T x, T y) {
// ...
}
}
μ λ€λ¦ λ©μλλ, λ©μλμ μ μΈλΆμ <T> κ° μ μΈλ λ©μλλ₯Ό λ§νλ€.
μμμλ ν΄λμ€μ μ λ€λ¦ <T> μμ μ€μ λ νμ
μ λ°μμ λ°ν νμ
μΌλ‘ μ¬μ©ν λΏμΈ μΌλ° λ©μλλΌλ©΄, μ λ€λ¦ λ©μλλ μ§μ λ©μλμ <T> μ λ€λ¦μ μ€μ ν¨μΌλ‘μ λμ μΌλ‘ νμ
μ λ°μμ μ¬μ©ν μ μλ λ
립μ μΌλ‘ μ΄μ© κ°λ₯ν μ λ€λ¦ λ©μλλΌκ³ μ΄ν΄νλ©΄ λλ€.
class FruitBox<T> {
// ν΄λμ€μ νμ
νλΌλ―Έν°λ₯Ό λ°μμ μ¬μ©νλ μΌλ° λ©μλ
public T addBox(T x, T y) {
// ...
}
// λ
립μ μΌλ‘ νμ
ν λΉ μ΄μλλ μ λ€λ¦ λ©μλ
public static <T> T addBoxStatic(T x, T y) {
// ...
}
}
μ¦, μ λ€λ¦ ν΄λμ€μ μ μλ νμ 맀κ°λ³μμ μ λ€λ¦ λ©μλμ μ μλ νμ 맀κ°λ³μλ λ³κ°μΈκ² λλ κ²μ΄λ€. μ λ€λ¦ λ©μλμ μ λ€λ¦ νμ μ μΈ μμΉλ λ©μλ λ°ν νμ λ°λ‘ μμ΄λ€.
μ λ€λ¦ λ©μλ νΈμΆ μ리
κ·ΈλΌ μ λ€λ¦ λ©μλλ₯Ό νΈμΆμ μ΄λ»κ² ν κΉ?
μ λ€λ¦ νμ μ λ©μλλͺ μμ μ§μ ν΄μ€¬μΌλ, νΈμΆ μμ λ©μλ μΌμͺ½μ μ λ€λ¦ νμ μ΄ μμΉνκ² λλ€.
FruitBox.<Integer>addBoxStatic(1, 2);
FruitBox.<String>addBoxStatic("μλ
", "μκ°");
μ΄λ μ»΄νμΌλ¬κ° μ λ€λ¦ νμ μ λ€μ΄κ° λ°μ΄ν° νμ μ λ©μλμ 맀κ°λ³μλ₯Ό ν΅ν΄ μΆμ ν μ μκΈ° λλ¬Έμ, λλΆλΆμ κ²½μ° μ λ€λ¦ λ©μλμ νμ νλΌλ―Έν°λ₯Ό μλ΅νκ³ νΈμΆν μ μλ€.
// λ©μλμ μ λ€λ¦ νμ
μλ΅
FruitBox.addBoxStatic(1, 2);
FruitBox.addBoxStatic("μλ
", "μκ°");
κ·Έλ°λ° νκ°μ§ κΆκΈν μ μ΄ μμ κ²μ΄λ€. ν΄λμ€ μμ λΆμ΄μλ μ λ€λ¦κ³Ό μ λ€λ¦ λ©μλλ λκ°μ <T> μΈλ° μ΄λ»κ² μ λ€λ¦ λ©μλλ§μ΄ λ
립μ μΌλ‘ μ΄μ©λλμ§ λ§μ΄λ€.
μ¬μ€μ μ²μ μ λ€λ¦ ν΄λμ€λ₯Ό μΈμ€ν΄μ€ννλ©΄, ν΄λμ€ νμ 맀κ°λ³μμ μ λ¬ν νμ μ λ°λΌ μ λ€λ¦ λ©μλλ νμ μ΄ μ ν΄μ§κ² λλ€. κ·Έλ°λ° λ§μΌ μ λ€λ¦ λ©μλλ₯Ό νΈμΆν λ μ§μ νμ νλΌλ―Έν°λ₯Ό λ€λ₯΄κ² μ§μ ν΄μ£Όκ±°λ, λ€λ₯Έ νμ μ λ°μ΄ν°λ₯Ό 맀κ°λ³μμ λκΈ΄νλ©΄ λ 립μ μΈ νμ μ κ°μ§ μ λ€λ¦ λ©μλλ‘ μ΄μ©λκ² λλ€.
class FruitBox<T, U> {
// λ
립μ μΌλ‘μ΄μλλ μ λ€λ¦ λ©μλ
public <T, U> void printBox(T x, U y) {
// ν΄λΉ 맀κ°λ³μμ νμ
μΆλ ₯
System.out.println(x.getClass().getSimpleName());
System.out.println(y.getClass().getSimpleName());
}
}
public static void main(String[] args) {
FruitBox<Integer, Long> box1 = new FruitBox<>();
// μΈμ€ν΄μ€νμ μ§μ λ νμ
νλΌλ―Έν° <Integer, Long>
box1.printBox(1, 1);
// νμ§λ§ μ λ€λ¦ λ©μλμ λ€λ₯Έ νμ
νλΌλ―Έν°λ₯Ό μ§μ νλ©΄ λ
립μ μΌλ‘ μ΄μ© λλ€.
box1.<String, Double>printBox("hello", 5.55);
box1.printBox("hello", 5.55); // μλ΅ κ°λ₯
}
μ λ€λ¦ νμ λ²μ νμ νκΈ°
μ λ€λ¦μ νμ μ μ§μ ν΄μ€μΌλ‘μ ν΄λμ€μ νμ μ μ»΄νμΌ νμμμ μ νμ¬ νμ μμΈμ λν μμ μ±μ ν보νλ κ²μ μ’μ§λ§ λ¬Έμ λ λ무 μμ λ‘λ€λ μ μ΄λ€.
μλ₯Όλ€μ΄ λ€μ κ³μ°κΈ° ν΄λμ€κ° μλ€κ³ νμ. μ μ, μ€μ ꡬλΆμμ΄ λͺ¨λ λ°μ μ μκ² νκΈ°μν΄ μ λ€λ¦μΌλ‘ ν΄λμ€λ₯Ό λ§λ€μ΄μ£Όμλ€. νμ§λ§ λ¨μν <T> λ‘ μ§μ νκ² λλ©΄ μ«μμ κ΄λ ¨λ λνΌ ν΄λμ€ λΏλ§ μλλΌ Stringμ΄λ λ€λ₯Έ ν΄λμ€λ€λ λμ
μ΄ κ°λ₯νλ€λ μ μ΄ λ¬Έμ μ΄λ€.
// μ«μλ§ λ°μ κ³μ°νλ κ³μ°κΈ° ν΄λμ€ λͺ¨λ
class Calculator<T> {
void add(T a, T b) {}
void min(T a, T b) {}
void mul(T a, T b) {}
void div(T a, T b) {}
}
public class Main {
public static void main(String[] args) {
// μ λ€λ¦μ μ무 νμ
μ΄λ λͺ¨λ ν λΉμ΄ κ°λ₯
Calculator<Number> cal1 = new Calculator<>();
Calculator<Object> cal2 = new Calculator<>();
Calculator<String> cal3 = new Calculator<>();
Calculator<Main> cal4 = new Calculator<>();
}
}
κ°λ°μμ μλλ‘λ κ³μ°κΈ° ν΄λμ€μ μ λ€λ¦ νμ νλΌλ―Έν°λ‘ Number μλ£νλ§ λ€μ΄μ€λλ‘ νκ³ λ¬Έμμ΄μ΄λ λ λ€λ₯Έ ν΄λμ€ μλ£νμ΄ λ€μ΄μ€λ©΄ μλκ² νκ³ μΆλ€κ³ νλ€. κ·Έλμ λμ¨ κ²μ΄ μ νλ νμ 맀κ°λ³μ (Bounded Type Parameter) μ΄λ€.
νμ νμ ν€μλ extends
κΈ°λ³Έμ μΈ μ©λ²μ <T extends [μ ννμ
]> μ΄λ€. μ λ€λ¦ <T> μ extends ν€μλλ₯Ό λΆμ¬μ€μΌλ‘μ¨, <T extends Number> μ λ€λ¦μ Number ν΄λμ€μ κ·Έ νμ νμ
(Integer, Double)λ€λ§ λ°λλ‘ νμ
νλΌλ―Έν° λ²μλ₯Ό μ ν ν κ²μ΄λ€.
ν΄λμ€μ μμ ν€μλμ μ λ€λ¦μ νμ νμ ν€μλκ° λλ€ λκ°μ΄ extends λΌ νΌλν μμ§κ° λ€λΆμ΄ μλ€. κΊΎμ κ΄νΈ μμ extendsκ° μμΌλ©΄ μ΄κ±΄ μ νμ μλ―Ένλ©° κ΄νΈ λ°κΉ₯μ μμΌλ©΄ μμμΌλ‘ 보면 λλ€.
μΈν°νμ΄μ€ νμ νμ
extends ν€μλ λ€μμ μ¬ νμ μ μΌλ° ν΄λμ€, μΆμ ν΄λμ€, μΈν°νμ΄μ€ λͺ¨λ μ¬ μ μλ€. μΈν°νμ΄μ€ λΆλΆμ μ½κ° νκΉλ¦΄μ μλλ°, ν΄λμ€μ μμ κ΄κ³μ λ€λ¦μ΄ μμΌλ κ·Έλλ‘ λΉλμ΄ μ μ©νλ©΄ λλ€.
interface Readable {
}
// μΈν°νμ΄μ€λ₯Ό ꡬννλ ν΄λμ€
public class Student implements Readable {
}
// μΈν°νμ΄μ€λ₯Ό Readableλ₯Ό ꡬνν ν΄λμ€λ§ μ λ€λ¦ κ°λ₯
public class School <T extends Readable> {
}
public static void main(String[] args) {
// νμ
νλΌλ―Έν°μ μΈν°νμ΄μ€λ₯Ό ꡬνν ν΄λμ€λ§μ΄ μ¬μ μκ² λ¨
School<Student> a = new School<Student>();
}
λ€μ€ νμ νμ
λ§μΌ 2κ° μ΄μμ νμ
μ λμμ μμ(ꡬν)ν κ²½μ°λ‘ νμ
μ ννκ³ μΆλ€λ©΄, & μ°μ°μλ₯Ό μ΄μ©νλ©΄ λλ€. ν΄λΉ μΈν°νμ΄μ€λ€μ λμμ ꡬνν ν΄λμ€κ° μ λ€λ¦ νμ
μ λμμ΄ λκ² λλ€.
λ¨, μλ°μμλ λ€μ€ μμμ μ§μνμ§ μκΈ° λλ¬Έμ ν΄λμ€λ‘λ λ€μ€ extendsλ λΆκ°λ₯νκ³ μ€λ‘μ§ μΈν°νμ΄μ€λ‘λ§μ΄ κ°λ₯νλ€.
interface Readable {}
interface Closeable {}
class BoxType implements Readable, Closeable {}
class Box<T extends Readable & Closeable> {
List<T> list = new ArrayList<>();
public void add(T item) {
list.add(item);
}
}
public static void main(String[] args) {
// Readable μ Closeable λ₯Ό λμμ ꡬνν ν΄λμ€λ§μ΄ νμ
ν λΉμ΄ κ°λ₯νλ€
Box<BoxType> box = new Box<>();
// μ¬μ§μ΄ μ΅μμ Object ν΄λμ€μ¬λ ν λΉ λΆκ°λ₯νλ€
Box<Object> box2 = new Box<>(); // ! Error
}
μ λ€λ¦μ΄ μ¬λ¬κ°μΈ λ€μ€ νμ νλΌλ―Έν°λ₯Ό μ¬μ©ν κ²½μ°μλ κ°κ° λ€μ€ μ νμ κ±°λ κ²λ κ°λ₯νλ€. (κ°λ μ±μ΄ μΌμ μ΄ λλ건 ν¨μ )
interface Readable {}
interface Closeable {}
interface Appendable {}
interface Flushable {}
class School<T extends Readable & Closeable, U extends Appendable & Closeable & Flushable>
void func(T reader, U writer){
}
}
μ¬κ·μ νμ νμ
μ¬κ·μ νμ νμ μ΄λ μκΈ° μμ μ΄ λ€μ΄κ° ννμμ μ¬μ©νμ¬ νμ 맀κ°λ³μμ νμ© λ²μλ₯Ό νμ μν€λ κ²μ λ§νλ€. μ€λ¬΄μμ μ£Όλ‘ Comparable μΈν°νμ΄μ€μ ν¨κ» μ°μΈλ€.
μλ₯Όλ€μ΄ λ€μκ³Ό κ°μ΄ <E extends Comparable<E>> μ λ€λ¦ Eμ νμ
λ²μλ₯Ό Comparable<E> λ‘ νμ νλ€λ Eλ₯Ό μ€μ²©μν¨ ννμμ μ¬μ©ν μ μλλ°, μ΄ λ§μ 'νμ
Eλ μκΈ° μμ μ μλΈ νμ
μΌλ‘ ꡬνν Comparable ꡬνμ²΄λ‘ νμ ' νλ€λ λ»μ΄λ€.
Comparableλ κ°μ²΄λΌλ¦¬ λΉκ΅λ₯Ό ν΄μΌ ν λ compareTo() λ©μλλ₯Ό μ€λ²λΌμ΄λ©ν λ ꡬννλ μΈν°νμ΄μ€μ΄λ€.
μλ°μμ Integer, Double, String λ±μ΄ κ° λΉκ΅κ° λλ μ΄μ κ° κΈ°λ³Έμ μΌλ‘ Comparableλ₯Ό ꡬννκ³ μκΈ° λλ¬Έμ΄λ€.
μ¦, Integer κ°μ²΄λ₯Ό μ λ€λ¦ νμ Eμ ν λΉνκ² λλ€λ©΄, Comparableμ ꡬνν κ°μ²΄λ©΄μ μ€λ‘μ§ κ°μ EμΈ Integer νμ λ§ λ°λλ€λ μλ―Έκ° λλ€. (μκΈ° μμ λ§ λ°λ λ€λ ννμ μ΄λ ΅κ² λΉλλ € ννν κ²μ΄λ€)
λ€μμ 컬λ μ μ μΈμλ‘ λ°μ 컬λ μ μ μμλ€μ μ΅λκ°(max)λ₯Ό κ΅¬ν΄ λ°ννλ λ©μλ μμ μ΄λ€. μ λ€λ¦ λ©μλ νμ μΌλ‘ μ¬κ·μ νμ νμ μ΄ μ¬μ©λμλ€.
class Compare {
// μΈλΆλ‘ λ€μ΄μ¨ νμ
Eλ Comparable<E>λ₯Ό ꡬνν E κ°μ²΄ μ΄μ΄μΌ νλ€.
public static <E extends Comparable<E>> E max(Collection<E> collection) {
if(collection.isEmpty()) throw new IllegalArgumentException("컬λ μ
μ΄ λΉμ΄ μμ΅λλ€.");
E result = null;
for(E e: collection) {
if(result == null) {
result = e;
continue;
}
if(e.compareTo(result) > 0) {
result = e;
}
}
return result;
}
}
public static void main(String[] args) {
Collection<Integer> list = Arrays.asList(56, 34, 12, 31, 65, 77, 91, 88);
System.out.println(Compare.max(list)); // 91
Collection<Number> list2 = Arrays.asList(56, 34, 12, 31, 65, 77, 91, 88);
System.out.println(Compare.max(list2)); // ! Error - Number μΆμ λ©μλλ Comparableλ₯Ό ꡬννμ§μμκΈ° λλ¬Έμ λΆκ°λ₯
}
μ λ€λ¦ νλ³ν
μ λ€λ¦ μΊμ€ν λ¬Έμ
λ°°μ΄κ³Ό κ°μ μΌλ°μ μΈ λ³μ νμ κ³Ό λ¬λ¦¬ μ§λ€λ¦ μλΈ νμ κ°μλ νλ³νμ΄ λΆκ°λ₯νλ€. μ¬μ§μ΄ λμ λ νμ μ΄ ObjectμΌμ§λΌλ λ§μ΄λ€. μμ°μ€λ½κ² λ€νμ±μ΄ μ μ©λ κ²μ΄λΌ μκ°νμμ§λ§, μ€μ μ λ€λ¦μ μ λ¬λ°μ λ± κ·Έ νμ μΌλ‘λ§ μλ‘ μΊμ€ν μ΄ κ°λ₯ν κ²μ΄λ€.
μ²μμ μκ°ν νμ νλΌλ―Έν°μ λ€νμ±μ ν¬ν¨ μμλ‘μ κ°λ₯νλ€λκ±°μ§, νλ³νμ κ°μ²΄ λ κ°μ²΄λ₯Ό λ§νλ κ±°λ λ€λ₯Έ κ°λ μ΄λ€.
// λ°°μ΄μ OK
Object[] arr = new Integer[1];
// μ λ€λ¦μ ERROR
List<Object> list = new ArrayList<Integer>();
List<Object> listObj = null;
List<String> listStr = null;
// μλ¬. List<String> -> List<Object>
listObj = (List<String>) listStr;
// μλ¬. List<Object> -> List<String>
listStr = (List<Object>) listObj;
μ΄ νΉμ§μ΄ μ λ¬Έμ μκ° λλλ©΄μ μ λ€λ¦ κ°μ²΄μ μμλ₯Ό λ£κ±°λ κ°μ Έμ¬λ, μΊμ€ν λ¬Έμ λ‘ μΈν΄ μ λ‘μ¬νμ΄ λ°μνκΈ° λλ¬Έμ΄λ€.
μλ₯Ό λ€μ΄ λ°°μ΄ κ°μ κ²½μ° λ°λ³΅λ¬Έμ λ³μλ‘ Object νμ μΌλ‘ λ°μ μ¬μ©ν΄λ λ¬Έμ κ° μλ€.
public static void main(String[] args) {
Apple[] integers = new Apple[]{
new Apple(),
new Apple(),
new Apple(),
};
print(integers);
}
public static void print(Fruit[] arr) {
for (Object e : arr) {
System.out.println(e);
}
}
νμ§λ§ μμ μ½λμμ λ°°μ΄μ 리μ€νΈμ μ λ€λ¦μΌλ‘ λ°κΎΈλ©΄ μ»΄νμΌ μλ¬κ° λ°μνλ€.
public static void main(String[] args) {
List<Integer> lists = new ArrayList<>(Arrays.asList(1, 2, 3));
print(lists); // ! μ»΄νμΌ μλ¬ λ°μ
}
public static void print(List<Object> list) {
for (Object e : list) {
System.out.println(e);
}
}
λ°°μ΄ κ°μ κ²½μ° print λ©μλμ 맀κ°λ³μλ‘ μκ·λ¨ΌνΈκ° λμ΄κ°λ Integer[] λ°°μ΄ νμ
μ΄ Object[] λ°°μ΄ νμ
μΌλ‘ μ
μΊμ€ν
μ΄ μ μ©λμ΄ λ¬Έμ κ° μμ§λ§, μ λ€λ¦ κ°μ κ²½μ° νμ
νλΌλ―Έν°κ° μ€λ‘μ§ λκ°μ νμ
λ§ λ°κΈ° λλ¬Έμ λ€νμ±μ μ΄μ©ν μ μμ΄μ κ·Έλ° κ²μ΄λ€.
μ λ€λ¦ μμΌλ μΉ΄λ
λ°λΌμ μ λ€λ¦ κ°μ νλ³νμ μ±λ¦½λκ² νκΈ° μν΄μλ μ λ€λ¦μμ μ 곡νλ μμΌλ μΉ΄λ ? λ¬Έλ²μ μ΄μ©νμ¬μΌ νλ€.
<?>: Unbounded Wildcards (μ ν μμ)- νμ νλΌλ―Έν°λ₯Ό λμΉνλ ꡬ체μ μΈ νμ μΌλ‘ λͺ¨λ ν΄λμ€λ μΈν°νμ΄μ€ νμ μ΄ μ¬ μ μλ€
<? extends μμνμ >: Upper Bounded Wildcards (μμ ν΄λμ€ μ ν)- νμ νλΌλ―Έν°λ₯Ό λμΉνλ ꡬ체μ μΈ νμ μΌλ‘ μμ νμ μ΄λ μμ νμ μ νμ νμ λ§ μ¬ μ μλ€
<? super νμνμ >: Lower Bounded Wildcards (νμ ν΄λμ€ μ ν)- νμ νλΌλ―Έν°λ₯Ό λμΉνλ ꡬ체μ μΈ νμ μΌλ‘ νμ νμ μ΄λ νμ νμ μ μμ νμ λ§ μ¬ μ μλ€
List<? extends Object> list = new ArrayList<String>();
List<? super String> list2 = new ArrayList<Object>();
public static void main(String[] args) {
List<Integer> lists = new ArrayList<>(Arrays.asList(1, 2, 3));
print(lists); // OK
}
// Numberμ κ·Έ νμ νμ
(Integer, Double λ±) λ§μ λ°λλ€
public static void print(List<? extends Number> list) {
for (Object e : list) {
System.out.println(e);
}
}
μ λ€λ¦ μμΌλ μΉ΄λ λ¬Έλ²μ μλ°μ μ λ€λ¦μμ κ°μ₯ λμ΄λκ° λμ λΆλΆμ΄λ€. μΈμ <? extends μμνμ
> λ₯Ό μ¨μΌλκ³ μΈμ <? super νμνμ
> μ¨μΌνλμ§λ νμ
κ°λ°μλ λλλ‘ μ΄λ €μ νλ λΆλΆμ΄λ€. λ°λΌμ λ³λμ μλ ν¬μ€ν
μ ν΅ν΄ μ λ€λ¦ μμΌλμΉ΄λ μ¬μ©λ²μ μλ²½ν μ΄ν΄ν΄λ³΄λλ‘ νμ.
μ λ€λ¦ νμ μκ±°
μ λ€λ¦μ νμ μμ μ±μ μν΄ JDK 1.5λΆν° λμ λ λ¬Έλ²μΌλ‘ μ΄μ μλ°μμλ μ λ€λ¦ νμ νλΌλ―Έν° μμ΄ μλ° μΈμ΄λ₯Ό μ½λ©ν΄μλ€. κ·Έλμ μ΄μ μ μλ° λ²μ μ μ½λμ νΈνμ±μ μν΄ μ λ€λ¦ μ½λλ μ»΄νμΌλλ©΄ μ λ€λ¦ νμ μ μ¬λΌμ§κ² λλ€. μ¦, ν΄λμ€ νμΌ(.class)μλ μ λ€λ¦ νμ μ λν μ 보λ μ‘΄μ¬νμ§ μλ κ²μ΄λ€.
μ΄μ°λ³΄λ©΄ μ λ€λ¦μ μ€μ λ°μ΄νΈ μ½λμλ μλ λ°μͺ½μ§λ¦¬ μΈμ΄ λ¬Έλ²μ΄λΌκ³ ν μ μλ€. κ·Έλμ μ λ€λ¦μ κ°λ°μκ° μλͺ»λ λ°©ν₯μΌλ‘ μ€κ³λ₯Ό νλ©΄ μ μ¬μ μΈ ν μ€μΌ(heap pollution) λ¬Έμ μ λΉ μ§κ² λ μ μλ€. λ°λΌμ μ°λ¦¬κ° λ°μ΄νΈ μ½λλ₯Ό λ³΄κ³ μ½λ©ν κ²μ μλμ§λ§, μ¬λ°λ₯΄κ² μ λ€λ¦μ μ€κ³νκΈ° μν΄μ μ λ€λ¦μ μ»΄νμΌ κ³Όμ μ νλ² μ―€ μμλ νμμ±μ΄ μλ€.
# μ°Έκ³ μλ£
https://www.youtube.com/watch?v=Vv0PGUxOzq0
https://www.youtube.com/watch?v=w5AKXDBW1gQ