Chapter 5 μ λ€λ¦
Item 26 λ‘ νμ μ μ¬μ©νμ§ λ§λΌ
μ λ€λ¦ νμ μ κ°κ° μΌλ ¨μ 맀κ°λ³μν νμ (parameterized type) μ μ μ νλ€.
μ λ€λ¦ νμ
μ νλ μ μνλ©΄ κ·Έμ λΈλ¦° λ‘ νμ
(row type) λ ν¨κ» μ μλλ€.
μ΄λ μ λ€λ¦ νμ
μμ νμ
맀κ°λ³μλ₯Ό μ ν μ¬μ©νμ§ μλ λλ₯Ό λ§νλ€.
λ‘ νμ
μ νμ
μ μΈμμ μ λ€λ¦ νμ
μ λ³΄κ° μ λΆ μ§μμ§ κ²μ²λΌ λμνλλ°,
μ λ€λ¦μ΄ λλνκΈ°μ μ μ μ½λμ νΈνλλλ‘ νκΈ° μν κΆμ¬μ§μ±
μ΄λ€.
μ λ€λ¦μμ λ‘ νμ
μ μ λ€λ¦μ΄ μ겨주λ μμ μ±κ³Ό ννλ ₯μ λͺ¨λ μΌκ² λκΈ° λλ¬Έμ μ¬μ©μ΄ μ§μλλ
μ λ€λ¦ λ±μ₯ μ΄μ μ μ¬μ©νλ μ½λλ€μ΄ μ λ€λ¦μ μ§μνμ§ μκΈ° λλ¬Έμ
λ‘ νμ
μ μ§μνκ²λ λ§μ΄κ·Έλ μ΄μ
νΈνμ±μ μν΄ λ‘ νμ
μ μ§μνκ³
μ λ€λ¦μ ꡬνμλ μκ±° (erasure) λ°©μμ μ¬μ©νκΈ°λ‘ νλ€.
Item 27 λΉκ²μ¬ κ²½κ³ λ₯Ό μ κ±°νλΌ
μ λ€λ¦ μ¬μ©μ λ§μ μ»΄νμΌλ¬ κ²½κ³ λ₯Ό μ κ±°ν΄μΌ νλ€.
// Runtime Error
Set<Lark> exaltation = new HashSet();
// Success
Set<Lark> exaltation = new HashSet<>();
JDK 7 λΆν° μ§μνλ λ€μ΄μλͺ¬λ μ°μ°μ (<>
) λ₯Ό μ¬μ©νμ¬ νμ
μΆλ‘ μ μ¬μ©νμ¬ λΉκ²μ¬ κ²½κ³ λ₯Ό μ κ±°νμ.
λͺ¨λ λΉ κ²μ¬ κ²½κ³ λ₯Ό μ κ±°νλ©΄ νμ
μμ μ±μ΄ 보μ₯λλ©° λ° νμμμ ClassCaseException
μ΄ λ°μν μΌμ΄ μλ€.
κ²½κ³ λ₯Ό μ κ±°ν μ μμ§λ§ νμ
μ΄ μμ νλ€κ³ νμ νλ€λ©΄ @SuppressWarnings("unchecked")
Annotation μ μ¬μ©νμ¬ κ²½κ³ λ₯Ό μ¨κΈ°μ.
@SuppressWarnings("unchecked")
Annotation μ μ¬μ©ν λλ κ·Έ κ²½κ³ λ₯Ό 무μν΄λ μμ ν κ·Όκ±°λ₯Ό μ£ΌμμΌλ‘ λͺ
μν΄μ€μΌ νλ€.
Item 28 λ°°μ΄λ³΄λ€λ 리μ€νΈλ₯Ό μ¬μ©νλΌ
μλ μ½λλ RuntimeException μ λ°ννλ€.
Object[] objAry = new Long[1];
// ArrayStoreException μ λ°ν
objAry[0] = "νμ
μ΄ λ¬λΌ λ£μ μ μλ€.";
μ΄λ λ°°μ΄μ΄ 곡λ³νμ μ΄λΌ Long μ© μ μ₯μμ String μ λ£μμ μμ§λ§ μ»΄νμΌμμλ μμ μλ€.
// νΈνλμ§ μλ νμ
List<Object> = objList = new ArrayList<Long>();
objList.add("νμ
μ΄ λ¬λΌ λ£μ μ μλ€.");
μ μ½λλ μ»΄νμΌμμ μ€λ₯λ₯Ό κ²μ¦ ν μ μλ€.
λν λ°°μ΄μ μ€μ²΄ν (reify) λλ€.
μ΄λ λ°°μ΄μ λ°νμμλ μμ μ΄ λ΄κΈ°λ‘ ν μμμ νμ
μ μΈμ§νκ³ νμΈ νλ€. κ·Έλμ 곡λ³μμλ λΆκ΅¬νκ³ λ°νμμμ μλ‘ λ€λ₯Έ νμ
μ μ½μ
νμμλ ArrayStoreException
μ΄ λ°μνλκ²μ΄λ€.
μ΄μ λ°λλ‘ μ λ€λ¦μ λ°νμμμλ λ°μ΄ν° νμ
μ΄ μκ±°κ° λλ Type Erasure
νμμ΄ λ°μλλ€. μμνμ
μ μ»΄νμΌμμλ§ κ²μ¬νλ©° λ°νμμλ μ μ μλ€λ λ»μ΄λ€.
μ΄ Type Erasure
λ μ λλ¦μ΄ μ§μλκΈ° μ μ λ κ±°μ μ½λμ μ λ€λ¦ νμ
μ μμ‘°λ‘κ² μ¬μ© κ°λ₯νλλ‘ νλ μΌμ’
μ 맀컀λμ¦μΌλ‘ μνμ ν΄μ€λ€.
μ¬μ©λΆκ° μ λ€λ¦ μ ν
- μ λ€λ¦ νμ
::
new List<E>[]
- 맀κ°λ³μν νμ
::
new List<String>[]
- νμ
맀κ°λ³μ ::
new E[]
μ μΈκ°μ§ μ νμ νμ μ΄ μμ νμ§ μκΈ° λλ¬Έμ μ λ€λ¦ λ°°μ΄μ λ§λ€ μ μλ€.
μ΄λ E
List<E>
List<String>
μ κ°μ νμ
μ μ€μ²΄ν λΆκ° νμ
(non-reifiable type) μ΄λΌκ³ νλλ° μ€μ²΄ν λμ§ μμμ λ°νμμ μ»΄νμΌ ν λλ³΄λ€ μ 보λμ΄ μ κ² κ°μ§λ νμ
μ λ§νλ€.
μκ±° 맀컀λμ¦ λλ¬Έμ 맀κ°λ³μν νμ
κ°μ΄λ° μ€μ²΄ν λ μ μλ νμ
μ List<?>
μ Map<?, ?>
κ°μ λΉ νμ μμΌλμΉ΄λ νμ
λΏμ΄λ€.
λ°°μ΄μ λΉνμ μ μμΌλμΉ΄λ νμ
μΌλ‘ λ§λ€μ μμ§λ§ μ μ©νκ² μΈ μΌμ΄ κ±°μ μλ€.
μ€μ²΄ν λΆκ° νμ
μ μ¬μ©ν λλ μμ λ κ°λ³μΈμ(varags) λΌλ μλ―Έλ‘ @SafeVarargs
Annotation μ μ¬μ©νμ¬ λ체 κ°λ₯νλ€.
μμ±μμμ 컬λ μ μ λ°μ Chooser ν΄λμ€ λ¦¬νν λ§
public class Chooser {
private final Object[] choiceArray;
public Chooser(Collection choices) {
choiceArray = choices.toArray();
}
public Object choose() {
Random rnd = ThreadLocalRandom.current();
return choiceArray[rnd.nextInt(choiceArray.length)];
}
}
choose()
λ©μλλ₯Ό νΈμΆ ν λλ§λ€ λ°νλ Object
λ₯Ό μνλ νμ
μΌλ‘ ν λ°ν ν΄μΌ νκΈ° λλ¬Έμ νμ
μ΄ λ€λ₯Έ μμκ° λ€μ΄μμΌλ©΄ ν λ³ν μ€λ₯κ° λλ€
λλ¬Έμ ν΄λΉ ν΄λμ€λ₯Ό μ λ€λ¦μΌλ‘ λ³ννλ€.
public class Chooser<T> {
private final T[] choiceArray;
public Chooser(Collection<T> choices) {
choiceArray = choiceArray.toArray();
}
// choose λ©μλλ κ·Έλλ‘
}
Object[]
κ° T[]
μΌλ‘ λ³ν λμ§ μκΈ° λλ¬Έμ λͺ
μμ μΌλ‘ μΊμ€ν
ν΄μ€λ€.
public class Chooser<T> {
private final T[] choiceArray;
public Chooser(Collection<T> choices) {
choiceArray = (T[]) choiceArray.toArray();
}
// choose λ©μλλ κ·Έλλ‘
}
T[]
κ° λ¬΄μ¨ νμ
μΈμ§ μ μ μμΌλ ν λ³νμ΄ λ°νμμ μμ ν¨μ 보μ₯ν μ μλ€λ κ²½κ³ κ° λ¬λ€.
λΉκ²μ¬ ν λ³ν κ²½κ³ μ΄κΈ° λλ¬Έμ λ°°μ΄ λμ 리μ€νΈλ₯Ό μ¬μ©νλ€.
public class Chooser<T> {
private final List<T> choiceList;
public Chooser(Collection<T> choices) {
choiceList = new ArrayList<>(choices);
}
public T choose() {
Random rnd = ThreadLocalRandom.current();
return choiceList.get(rnd.nextInt(choiceList.size()));
}
}
μ½λλμ μ‘°κΈλ λμκ³ μλ§λ μ‘°κΈλ λ리μ§λ§,
λ°νμμ ClassCastException
μ΄ λ°μλ 리μ€ν¬κ° μ€μλ€.
ν΅μ¬ μ 리
λ°°μ΄μ κ³΅λ³ μ΄κ³ μ€μ²΄ν λλ λ°λ©΄,
μ λ€λ¦μ λΆκ³΅λ³ μ΄κ³ νμ
μ λ³΄κ° μκ±° λλ€.
λ°°μ΄μ λ°νμμλ νμ
μ΄ μμ νμ§λ§ μ»΄νμΌ νμμλ μμ νμ§ μλ€.
μ λ€λ¦μ μ΄μ λ°λ μ¬μ κ·Έ λμ μμ΄ μ°κΈ°λ μ½μ§ μλ€.
λμ μμ΄ μ°λ€ μ»΄νμΌ μ€λ₯λ κ²½κ³ λ₯Ό λ§λλ©΄ κ°μ₯ λ¨Όμ λ°°μ΄μ 리μ€νΈλ‘ λ체νλ λ°©λ²μ μ μ© ν΄λ³΄μ.
Item 29 μ΄μμ΄λ©΄ μ λ€λ¦ νμ μΌλ‘ λ§λ€λΌ
ν΄λΌμ΄μΈνΈμμλ μ§μ ν λ³νν΄μΌ νλ νμ λ³΄λ€ μ λ€λ¦ νμ μ΄ λ μμ νκ³ μ°κΈ° νΈνλ€.
μλ‘μ΄ νμ μ μ€κ³ν λλ ν λ³ν μμ΄λ μ¬μ©ν μ μλλ‘ μ λ€λ¦ νμ μΌλ‘ λ§λ€μ΄μΌ ν κ²½μ°κ° λ§λ€.
λ€μμ Stack
ν΄λμ€λ μ λ€λ¦ νμ
μΌλ‘ 리νν λ§ νλ κ³Όμ μ΄λ€.
public class Stack {
private Object[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16;
public Stack() {
elements = new Object[DEFAULT_INITAL_CAPACITY];
}
public void push(Object e) {
ensureCapacity();
elements[size++] = e;
}
public Object pop() {
if (size == 0)
throw new EmptyStackException();
Object result = elements[--size];
// μ¬μ©μ΄ λλ μ°Έμ‘°λ₯Ό ν΄μ
elements[size] = null;
return result;
}
public boolean isEmpty() {
return size == 0;
}
private void ensureCapacity() {
if (elements.length == size)
elements = Arrays.copyOf(elements, 2 * size + 1);
}
}
Object
λ₯Ό μ λ€λ¦ νμ
μΌλ‘ λ³κ²½νλ€.
public class Stack<E> {
private E[] elements;
private int size = 0;
private static final int DEFAULT_INITAL_CAPACITY = 16;
public Stack() {
elements = new E(DEFAULT_INITAL_CAPACITY);
}
public void push(E e) {
ensureCapacity();
elements[size++] = e;
}
public E pop() {
if (size == 0)
throw new EmptyStackException();
E result = elements[--size];
// μ¬μ©μ΄ λλ μ°Έμ‘° ν΄μ
elements[size] = null;
return result;
}
}
μλμ κ°μ E
λ μ€μ²΄ν λΆκ° νμ
μΌλ‘ λ°°μ΄μ λ§λ€μ μμ΄ μλμ κ°μ μλ¬λ₯Ό λ±λλ€.
Stack.java:8: generic array creation
elements = new E[DEFAULT_INITIAL_CAPACITY];
μ΄ κ²½κ³ λ λΉκ²μ¬ νλ³νμ΄ νλ‘κ·Έλ¨μ μμ μ±μ ν΄μΉ μ μλ€λ μλ―Έμ΄λ―λ‘ μ€μ€λ‘ νμΈν΄μΌ νλ€.
- λ°°μ΄μ
elements
λprivate
νλμ μ μ₯λλ€. - Client λ‘ λ°νλκ±°λ λ€λ₯Έ λ©μλμ μ λ¬λλ μΌμ΄ μ ν μλ€.
push()
λ©μλλ₯Ό ν΅ν΄ λ°°μ΄μ μ μ₯λλ μμμ νμ μ νμ E λ€.
νμ μ 3κ°μ§ 쑰건μ λ§μ‘±νλ―λ‘ μ΄ μ½λμ λΉκ²μ¬ νλ³νμ μμ νλ€.
μλμ κ°μ΄ μ λ€λ¦ λ°°μ΄ μμ±μ κΈμ§νλ μ μ½μ μ°ννλ λ°©λ²μΌλ‘
Object
λ°°μ΄μ μμ±ν λ€μ μ λ€λ¦ λ°°μ΄λ‘ νλ³ν νλ λ°©λ²μ΄ μλ€.
νμ§λ§ μ΄λ μ€λ₯λμ κ²½κ³ λ₯Ό λ΄λ³΄λΈλ€.
μλ μ½λμ κ°μ΄ μμ±μ λ©μλλ₯Ό @SuppressWarnings("unchecked")
μ λν
μ΄μ
μΌλ‘ ν΄λΉ κ²½κ³ λ₯Ό μ¨κΈ΄λ€.
λ°°μ΄ elements
μ push(E)
λ‘ λμ΄μ¨ μΈμ€ν΄μ€ E
λ§ λ΄λλ€.
@SuppressWarnings("unchecked")
public Stack() {
elements = (E[]) new Object[DEFAULT_INITAL_CAPACITY];
}
μ μ½λλ νμ
μ μμ μ±μ 보μ₯νμ§λ§ μ΄ λ°°μ΄μ λ°νμ
μ E[]
κ° μλ Object[]
μ΄λ€.
μλμ κ°μ΄ λ°°μ΄ κ°μ²΄ elements
νλ³ν ν μ μλ€λ μλ¬κ° λ¬λ€.
Stack.java:19: incompatible types found: Object, required: E
E result = elements[--size];
λ°°μ΄μ΄ λ°νν μμλ₯Ό E
λ‘ νλ³ν νλ©΄ μ€λ₯λμ κ²½κ³ κ° λ¬λ€.
Stack.java:19: warning: [unchecked] unchecked cast found: Object, required: E
E result = (E) elements[--size];
μ μ½λμμμ κ²½κ³ E
λ μ€μ²΄ν λΆκ° νμ
μ΄λ―λ‘ λ°νμμ μ΄λ£¨μ΄μ§λ νλ³νμ΄ μμ νμ§ μ¦λͺ
ν λ°©λ²μ΄ μλ€.
νμ§λ§ push()
λ©μλμμλ E
νμ
λ§ νμ©νλ―λ‘ μ νλ³νμ μμ νλ€.
νλ³νμ΄ μμ νλ€ μκ°μ΄ λ€λ©΄ λΉκ²μ¬ κ²½κ³ λ₯Ό μ¨κΈ΄λ€.
public E pop() {
if (size == 0)
throw new EmptyStackException();
@SuppressWarnings("unchecked")
E result = (E) elements[--size];
// μ¬μ©μ΄ λλ μ°Έμ‘°λ₯Ό ν΄μ
elements[size] = null;
return result;
}
Item 28 μμμ λ°°μ΄λ³΄λ€λ 리μ€νΈλ₯Ό μ°μ νλΌλ μν©μ λ°λΌ λ€λ₯΄λ©°
μ λ€λ¦ νμ
μμμ 리μ€νΈλ₯Ό μ¬μ©νλκ² νμ κ°λ₯νμ§λ λ μ’μ λ°©λ²μ΄ μλμλ μλ€.
μλ°κ° 리μ€νΈλ₯Ό κΈ°λ³Ένμ
μΌλ‘ μ 곡νμ§ μμΌλ―λ‘ ArrayList
μ κ°μ μ λ€λ¦ νμ
λ κ²°κ΅μ κΈ°λ³Έ νμ
μΈ λ°°μ΄μ μ¬μ©ν΄ ꡬνν΄μΌ νλ κ²½μ°λ μλ€.
HashMap
κ³Ό κ°μ μ λ€λ¦ νμ
μ μ±λ₯μ λμΌ λͺ©μ μΌλ‘ λ°°μ΄μ μ¬μ©νκΈ°λ νλ€.
μ λ€λ¦ νμ
μ νμ
맀κ°λ³μμ μ΄λ ν μ μ½μ λκ³ μμ§λ μμ§λ§ κΈ°λ³Ένμ
μ μ¬μ©ν μ μλ€.
κ°λ Ή Stack<int>
Stack<double>
μ λ§λλ €κ³ νλ©΄ μ»΄νμΌ μ€λ₯κ° λλ€.
μ΄λ μλ°μ κ·Όλͺ¬μ μΈ λ¬Έμ μ΄λ, λ°μ±λ κΈ°λ³Ένμ
μ μ¬μ©νμ¬ μ°νκ° κ°λ₯νλ€.
νΉμ νμ
맀κ°λ³μμ μ μ½μ λμ΄ μ¬μ©νλ λ°©λ²λ μλ€. (νμ μ νμ
맀κ°λ³μ)
μλ₯Ό λ€λ©΄ java.util.concurrent.DelayQueue κ³Ό κ°μ΄ DelayQueue
μμ κ³Ό DelayQueue
μ μμλ₯Ό μ¬μ©νλ Delayed
ν΄λμ€μμ ClassCastException
κ±±μ ν νμ μμ΄ μ¬μ© κ°λ₯νλ€.
Item 30 μ΄μμ΄λ©΄ μ λ€λ¦ λ©μλλ‘ λ§λ€λΌ
ν΄λμ€μ λ§μ°¬κ°μ§λ‘ λ©μλλ μ λ€λ¦μΌλ‘ λ§λ€μ μλ€.
맀κ°λ³μν νμ
μ λ°λ μ μ μ νΈλ¦¬ν° λ©μλλ μ λ€λ¦μΌλ‘ λνμ μΌλ‘ Collections
μ μκ³ λ¦¬μ¦ λ©μλλ λͺ¨λ μ λ€λ¦ λ©μλμ΄λ€.
public static Set union(Set s1, Set s2) {
Set result = new HashSet(s1);
result.addAll(s2);
return result;
}
μ μ½λλ μ»΄νμΌμ λμ§λ§ κ²½κ³ κ° λκ°κ° λ°μνλ€.
Union.java:5: warning: [unchecked] unchecked call to HashSet(Collection<? extends E>) as a member of raw type HashSet
Set result = new HashSet(s1);
Union.java:6: warning: [unchecked] unchecked call to addAll(Collection<? extends E>) as a member of raw type Set
result.addAll(s2);
μ κ²½κ³ λ λ©μλ νμ μ μμ μ±μ 보μ₯ν΄μΌ νλ€.
public static <E> Set<E> union(Set<E> s1, Set<E> s2) {
Set<E> result = new HashSet<>();
result.addAll(s2);
return result;
}
λ¨μν μ λ€λ¦ λ©μλλΌλ©΄ μ μ½λμ λκ° μ λΉνλ€.
μ΄ λ©μλλ κ²½κ³ μμ΄ μ»΄νμΌ λλ©°, μμ νκ³ μ°κΈ°λ μ½λ€.
public static void main(String[] args) {
Set<String> guys = Set.of("ν°", "λ", "ν΄λ¦¬");
Set<String> stooges = Set.of("λ리", "λͺ¨μ", "컬리");
Set<String> aflCio = union(guys, stooges);
System.out.println(aflcio);
}
μ νλ‘κ·Έλ¨μ μ€νμμΌ°μλμ κ²°κ³Όλ μλμ κ°λ€.
[λͺ¨μ, ν°, ν΄λ¦¬, λ리, 컬리, λ]
νλ±ν¨μ λ μ
λ ₯κ°μ μμ μμ΄ κ·Έλλ‘ λ°ννλ νΉλ³ν ν¨μλ‘
μ΄λ₯Ό μ΄μ©ν μ λ€λ¦ μ±κΈν΄ λ°©μλ₯Ό λ§λ€λ©΄ μλμ μμμ κ°λ€.
public static UnaryOperator<Object> IDENTITY_FN = (t) -> t;
@SuppressWarning("unchecked")
public static <T> UnaryOperator<T> identityFunction() {
return (UnaryOperator<T>) IDENTITY_FN
}
μ λΉκ²μ¬ κ²½κ³ μ λν
μ΄μ
μ T
κ° μ΄λ€ νμ
μ΄λ UnaryOperator<Object>
λ UnaryOperator<T>
κ° μλκΈ° λλ¬Έμ΄λ€ (νμ
μκ±°)
νμ§λ§ νλ± ν¨μλ T
κ° μ΄λ€ νμ
μ΄λ μ
λ ₯ κ°μ κ·Έλλ‘ λ°ννκΈ° λλ¬Έμ UnaryOperator<T>
λ₯Ό μ¬μ©ν΄λ μμ νλ€.
Item 31 νμ μ μμΌλμΉ΄λλ₯Ό μ¬μ©ν΄ API μ μ°μ±μ λμ΄λΌ
맀κ°λ³μν νμ (Parameterized Types) μ λΆκ³΅λ³ (invariant) μ΄λ€.
μμΌλμΉ΄λ νμ
μ μ¬μ©νμ§ μμ pushAll()
λ©μλλ κ²°ν¨μ΄ μλ€.
public void pushAll(Iterable<E> src) {
for (E e : src) {
push(e);
}
}
Integer
λ Number
μ νμνμ
μ΄λ μ λμ ν΄μΌ νλ€. (리μ€μ½ν μΉν λ²μΉ)
Stack<Number> numberStack = new Stack();
Iterable<Integer> integers = ...;
numberStack.pushAll(integers);
νμ§λ§ μλμ κ°μ΄ μ€λ₯ λ©μΈμ§κ° λ¬λ€.
맀κ°λ³μν νμ
μ΄ λΆκ³΅λ³μ΄κΈ° λλ¬Έ μ΄λ€.
StackTest.java:7: error: incompatible types: Iterable<Integer> cannot be converted to Iterable<Number>
numberStack.pushAll(integers);
μ μλ¬λ₯Ό κ³ μΉκΈ° μν΄μ μλ°λ νμ μ μμΌλ μΉ΄λ νμ
μ΄λΌλ νΉλ³ν 맀κ°λ³μν νμ
μ μ§μ νλ€.
pushAll()
μ μ
λ ₯ 맀κ°λ³μ νμ
μ E
μ Iterable
μ΄ μλλΌ E
μ νμ νμ
μ Iterable
μ΄μ¬μΌ νλ©° μμΌλ μΉ΄λμ νμ
μ Iterable<? extends E>
μ΄ λμ΄μΌ νλ€.
μμ°μ (Producer) μ μν 맀κ°λ³μν νμ μ μ μ©
public void pushAll(Iterable<? extends E> src) {
for (E e : src) {
push(e);
}
}
popAll()
λ©μλ λν μμΌλμΉ΄λμ λ―Έμ μ©μΌλ‘ μΈν΄ κ²°ν¨μ΄ μκΈ΄λ€.
Stack<Number> numberStack = new Stack<>();
Collection<Object> objects = ...;
numberStack.popAll(objects);
μ μ½λλ₯Ό μ»΄νμΌ νλ©΄ Collection<Object>
λ Collction<Number>
μ νμνμ
μ΄ μλλ€ λΌλ λ©μΈμ§μ ν¨κ» μ€λ₯κ° λ°μνλ€.
μ΄ κ²½μ°μλ νμ μ μμΌλμΉ΄λ νμ
μ μ μ©νμ¬ ν΄κ²°νλ€.
popAll()
μ μ
λ ₯ 맀κ°λ³μ νμ
μ΄ E
μ Collection μ΄ μλλΌ E
μ μμ νμ
μ Collection μ΄μ¬μΌ νλ©° μμΌλ μΉ΄λμ νμ
μ Collection<? super E>
κ° λμ΄μΌ νλ€.
μλΉμ (Consumer) 맀κ°λ³μμ μμΌλμΉ΄λ νμ μ μ μ©
public void popAll(Collection<? super E> dst) {
while(!isEmpty())
dst.add(pop());
}
PECS
μμ κ°μ ν¨ν΄μ PECS (Producer Extends & Consumer Super) λΌκ³ νλ©° 맀κ°λ³μλ₯Ό μ μ°μ±μκ² μμΌλμΉ΄λλ₯Ό μ¬μ©νκ²λ λμμ€λ€.
맀κ°λ³μν νμ
T
μμ° λ° μλΉμ λ§κ² νμ μ μμΌλ μΉ΄λκ° λΆλ¦¬λλ€.
- μμ°μ :
<? extends T>
- μλΉμ :
<? super T>
Item 32 μ λ€λ¦κ³Ό κ°λ³μΈμλ₯Ό ν¨κ» μΈ λλ μ μ€νλΌ
μ€μ²΄ν λΆκ° νμ (non-reifiable type) μ λ°νμμλ μ»΄νμΌ νμλ³΄λ€ νμ κ΄λ ¨ μ 보λ₯Ό μ κ² λ΄κ³ μλ€.
λ©μλλ₯Ό μ μΈν λ μ€μ²΄ν λΆκ° νμ
μΌλ‘ varargs
맀κ°λ³μλ₯Ό μ μΈνλ©΄ μ»΄νμΌλ¬κ° κ²½κ³ λ₯Ό 보λΈλ€.
warning: [unchecked] Possible heap pollution from
parameterized vararg type List<String>
맀κ°λ³μν νμ
(parameterized type) μ λ³μκ° λ€λ₯Έ κ°μ²΄λ₯Ό μ°Έμ‘°νλ©΄ ν (heap) μ€μΌμ΄ λ°μνλ€λ μλ―Έλ‘
λ€λ₯Έ νμ
μ κ°μ²΄λ₯Ό μ°Έμ‘°νλ μν©μμ μ»΄νμΌλ¬κ° μλ μμ±ν νλ³νμ΄ μ€ν¨ν μ μλ€.
μ λ€λ¦ κ°λ³μΈμ (varargs) λ°°μ΄ λ§€κ°λ³μμ κ°μ μ μ₯νλκ²μ μμ νμ§ μλ€.
μλ μμ λ₯Ό 보μ
static void dangerous(List<String>... stringLists) {
List<Integer> intList = List.of(42);
Object[] objects = stringLists;
objects[0] = intLists; // ν μ€μΌ λ°μ
String s = stringLists[0].get(0) // ClassCastException - ν λ³ν λ°μ
}
μλ°μμλ μ κ°μ μνμ±μ μΈμ§νκ³ λ λνμ μΌλ‘ μλμ κ°μ λ©μλλ₯Ό μ 곡νλ€.
Array.asList(T... a)
Collections.addAll(Collection<? super T> c, T... elements)
EnumSet.of(E first, E... rest)
μ λ€λ¦μ΄λ νΉμ 맀κ°λ³μν νμ
μ κ°λ³μΈμ (varargs) νμ
μ 맀κ°λ³μλ₯Ό λ°λ λͺ¨λ λ©μλμμλ @SafeVarargs
λ₯Ό λ¬μμ€μΌ νλ€.
μ΄λ κ°λ³μΈμ (varargs) νμ μ 맀κ°λ³μ λ°°μ΄μ μ무κ²λ μ μ₯ν΄μ μλλ©°, κ·Έ λ°°μ΄ νΉμ 볡μ λ³Έμ μ λ’°ν μ μλ μ½λμ λ ΈμΆνλ μλκ²μ΄ μμΉμ΄λ€.
Item 33 νμ μμ μ΄μ’ 컨ν μ΄λλ₯Ό κ³ λ €νλΌ
컨ν μ΄λ λμ ν€λ₯Ό 맀κ°λ³μν μν€κ³ , 컨ν μ΄λμ κ°μ λ£κ±°λ λΊ λ 맀κ°λ³μν ν ν€λ₯Ό ν¨κ» μ 곡νλ€.
public class Favorites {
public <T> void putFavorite(Class<T> type, T instance);
public <T> T getFavorite(Class<T> type);
}
public static void main(String[] args) {
Favorites f = new Favorites();
f.putFavorite(String.class, "Java");
f.putFavorite(Integer.class, 0xcafebabe);
f.putFavorite(Class.class, Favorites.class);
String favoriteString = f.getFavorite(String.class);
int favoriteInteger = f.getFavorite(Integer.class);
Class<?> favoriteClass = f.getFavorite(Class.class);
System.out.println("%s %x%n", favoriteString, favoriteInteger, favoriteClass.getName());
}
Java cafebabe Favorites
Favorites
μΈμ€ν΄μ€λ String μ μμ²νλλ° Integer λ₯Ό λ°ννλ μΌμ μ λ μλ€.
μ΄λ λͺ¨λ ν€μ νμ
μ΄ κ°κ° λΆλ¦¬λμ΄ μμ΄ μΌλ°μ μΈ λ°±κ³Ό λ¬λ¦¬ μ¬λ¬κ°μ§ νμ
μ μμλ₯Ό λ΄μ μ μλ€.
λ°λΌμ Favorites
μ νμ
μμ μ΄μ’
컨ν
μ΄λ λΌκ³ νλ€.
μλλ Favorites
μ ꡬνμ΄λ€.
public class Favorites {
private Map<Class<?>, Object> favorites = new HashMap<>();
public <T> void putFavorite(Class<T> type, T instance) {
favorites.put(Objects.requireNonNull(type), instance);
}
public <T> T getFavorite(Class<T> type) {
return type.cast(favorites.get(type));
}
}
μ°Έκ³ μλ£