νκΈ μ©μ΄ | μλ¬Έ μ©μ΄ | μ |
---|---|---|
맀κ°λ³μν νμ | parameterized type | List<String> |
μ€μ νμ λ§€κ° λ³μ | actual type parameter | String |
μ λ€λ¦ νμ | generic type | List<E> |
μ κ· νμ λ§€κ° λ³μ | formal type parameter | E |
λΉνμ μ μμΌλμΉ΄λ νμ | unbounded wildcard type | List<?> |
λ‘ νμ | raw type | List |
νμ μ νμ 맀κ°λ³μ | bounded type bound | <T extends Number> |
μ¬κ·μ νμ νμ | recursive type bound | <T extends Comparable<T>> |
νμ μ μμΌλμΉ΄λ νμ | bounded wildcard type | List<? extends Number> |
μ λ€λ¦ λ©μλ | generic method | static <E> List<E> asList(E[] a) |
νμ ν ν° | type token | String.class |
βλ‘ νμ μ μ¬μ©νλ©΄ λ°νμμ μμΈκ° μΌμ΄λ μ μμΌλ―λ‘ μ¬μ©νλ©΄ μ λ¨β
// Stamp μΈμ€ν΄μ€λ§ μ·¨κΈνλ€.
private final Collection stamps = ...;
// stampsμ λμ₯(Stamp) λμ λμ (Coin)μ λ£μ΄λ μ무 μ€λ₯ μμ΄ μ»΄νμΌλκ³ μ€ν λ¨
stamps.add(new Coin(...));
// 컬λ μ
μμ μ΄ λμ μ κΊΌλΌ λ, λ°νμ μμΈκ° λ°μ
for (Iterator i = stamps.iterator(); i.hasNext();) {
Stamp stamp = (Stamp) i.next(); // ClassCastExceptionμ λμ§λ€.
stamp.cancel();
}
String
μ Object
μ νμ νμ
μΈκ°? : νμνμ
μ΄λ€.List<String>
μ List
μ νμ νμ
μΈκ°? : νμνμ
μ΄λ€.List<String>
μ List<Object>
μ νμ νμ
μΈκ°? : μλλ€. μνκ΄κ³κ° μλ€.β 맀κ°λ³μν νμ κ°μλ μνκ΄κ³κ° μλ€.
β λ°λΌμ μλ μ½λλ μ»΄νμΌλμ§ μμ.
public class Raw {
public static void main(String[] args) {
List<String> strings = new ArrayList<>();
// List<String>μ΄ List<Object>μ νμνμ
μ΄ μλ.
unsafeAdd(strings, "test");
}
private static void unsafeAdd(List<Object> list, Object o) {
list.add(o);
}
}
public class Raw {
public static void main(String[] args) {
List<String> strings = new ArrayList<>();
// List<String>μ΄ List<Object>μ νμνμ
μ΄ μλ.
unsafeAdd(strings, "test");
}
// Objectλ₯Ό ?λ‘ λ°κΏμ£Όμμ.
private static void unsafeAdd(List<?> list, Object o) {
list.add(o);
}
}
?
)μ μ λ€λ¦ νμ
μ μ°κ³ μΆμ§λ§ μ€μ νμ
맀κ°λ³μκ° λ¬΄μμΈμ§ μ κ²½μ°κ³ μΆμ§ μμ λ μ¬μ©.List.class
, String[].class
, int.class
κ°λ₯ / List<String>.class
, List<?>.class
λΆκ°λ₯if(o instanceof Set) { ... }
βλΉκ²μ¬ κ²½κ³ λ μ€μνλ 무μνμ§ λ§μβ
// νμ
맀κ°λ³μλ₯Ό λͺ
μνμ§ μμ : λΉκ²μ¬ λ³ν κ²½κ³
Set<Lark> exaltation = new HashSet();
// λ€μ΄μλͺ¬λ μ°μ°μ(<>)λ‘ ν΄κ²° : μλ°7λΆν° νμ
맀κ°λ³μλ₯Ό μΆλ‘ ν΄ μ€
Set<Lark> exaltation = new HashSet<>();
ClassCastException
λ°μ μ λ X@SuppressWarnings(βuncheckedβ)
μ΄λ
Έν
μ΄μ
μ λ¬μ κ²½κ³ λ₯Ό μ¨κΈ°μ.@SuppressWarnings
μ΄λ
Έν
μ΄μ
μ νμ κ°λ₯ν ν μ’μ λ²μμ μ μ©νμ@SuppressWarnings(βuncheckedβ)
μ΄λ
Έν
μ΄μ
μ μ¬μ©ν λλ©΄ κ·Έ κ²½κ³ λ₯Ό 무μν΄λ μμ ν μ΄μ λ₯Ό νμ μ£ΌμμΌλ‘ λ¨κ²¨μΌ ν¨.λ°°μ΄ | 리μ€νΈ(μ λ€λ¦) | |
---|---|---|
λ¬Έλ² | String[] | List<String> |
--- | --- | --- |
μνκ΄κ³ | Subκ° Superμ νμ νμ
μΌ λ, Sub [] λ Super[] μ νμ νμ
β곡λ³(covariant) | Type1μ΄ Type2μ νμ νμ
μΌ λ, List <Type1> λ List<Type2> μ νμ νμ
λ μμ νμ
λ μλ (μνκ΄κ³ μμ).β λΆκ³΅λ³(invariant) |
--- | --- | --- |
νμ μμ | μ»΄νμΌ : νμ
μμ X λ°νμ : νμ μμ O β μ»΄νμΌ μμ μ νμ μμ μ±μ 보μ₯ λ°μ§ λͺ»νμ¬ λ°νμμ μμΈ λ°μ κ°λ₯ | μ»΄νμΌ : νμ
μμ O λ°νμ : νμ μμ X β μ»΄νμΌ μμ μ νμ μμ μ±μ 보μ₯ λ°μ |
--- | --- | --- |
μ€μ²΄ν | μ€μ²΄ν β λ°νμμλ μμ μ΄ λ΄κΈ°λ‘ ν μμμ νμ μ μΈμ§ & νμΈ | μ€μ²΄ν λΆκ°(μκ±° 맀컀λμ¦) β λ°νμμλ μμμ νμ μ 보λ₯Ό μ μ μμ(μ»΄νμΌ μμ μ νμ μ 보 μκ±°), λΉνμ μ μμΌλ μΉ΄λ νμ μ μμΈ. |
// λ°°μ΄μ 곡λ³μ΄λ―λ‘ μ μμ μΌλ‘ μ»΄νμΌ λ¨
Object[] objectArray = new Long[1];
objectArray[0] = "νμ
μ΄ λ¬λΌ λ£μ μ μλ€." // λ°νμμ ArrayStoreExceptionμ λμ§λ€
// μ λ€λ¦μ λΆκ³΅λ³μ΄λ―λ‘ μ»΄νμΌμ΄ μ€ν¨ ν¨
List<Object> ol = new ArrayList<Long>(); // νΈνλμ§ μλ νμ
ol.add("νμ
μ΄ λ¬λΌ λ£μ μ μλ€.");
β μ΄λ λ― λ°°μ΄μ μ€μλ₯Ό λ°νμμμΌ μκ² λμ§λ§, 리μ€νΈλ₯Ό μ¬μ©νλ©΄ μ»΄νμΌ μμ μ μ€μλ₯Ό λ°λ‘ μ‘μ μ μμ.
βν΄λΌμ΄μΈνΈμμ μ§μ νλ³νν΄μΌνλ νμ λ³΄λ€ μ λ€λ¦ νμ μ΄ λ μμ νκ³ μ°κΈ° νΈνλ€β
// E[]λ₯Ό μ΄μ©ν μ λ€λ¦ μ€ν
public class Stack<E> {
private E[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16;
// λ°°μ΄ elementsλ push(E)λ‘ λμ΄μ¨ E μΈμ€ν΄μ€λ§ λ΄λλ€.
// λ°λΌμ νμ
μμ μ±μ 보μ₯νμ§λ§,
// μ΄ λ°°μ΄μ λ°νμ νμ
μ E[]κ° μλ Object[]λ€!
@SuppressWarnings("unchecked")
public Stack() {
elements = (E[]) new Object[DEFAULT_INITIAL_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;
}
public boolean isEmpty() {
return size == 0;
}
private void ensureCapacity() {
if (elements.length == size)
elements = Arrays.copyOf(elements, 2 * size + 1);
}
}
Stack<Object>
, Stack<String>
λ± μ΄λ€ μ°Έμ‘° νμ
μΌλ‘λ Stackμ λ§λ€ μ μμ.Stack<int>
μ²λΌ κΈ°λ³Έ νμ
μ μ¬μ©ν μ μμ.<E extends Delayed>
: java.util.concurrent.Delayed
μ νμ νμ
λ§ λ°μ μ μμ.βν΄λΌμ΄μΈνΈμμ μ λ ₯ 맀κ°λ³μμ λ°νκ°μ λͺ μμ μΌλ‘ νλ³νν΄μΌ νλ λ©μλ보λ€
μ λ€λ¦ λ©μλκ° λ μμ νλ©° μ¬μ©νκΈ° μ½λ€β
// μ λ€λ¦ λ©μλ
public static <E> Set<E> union(Set<E> s1, Set<E> s2) {
Set<E> result = new HashSet<>(s1);
result.addAll(s2);
return result;
}
Comparable
μΈν°νμ΄μ€μ ν¨κ» μ°μ// 컬λ μ
μμ μ΅λκ°μ λ°ννλ€. - μ¬κ·μ νμ
νμ μ¬μ©
public static <E extends Comparable<E>> E max(Collection<E> c) {
if (c.isEmpty())
throw new IllegalArgumentException("컬λ μ
μ΄ λΉμ΄ μμ΅λλ€.");
E result = null;
for (E e : c)
if (result == null || e.compareTo(result) > 0)
result = Objects.requireNonNull(e);
return result;
}
<E extends Comparable<E>>
: βλͺ¨λ νμ
Eλ μμ κ³Ό λΉκ΅ν μ μλ€.ββPECS곡μμΌλ‘ APIλ₯Ό μ μ°νκ² λ§λ€μβ
T
κ° μμ°μλΌλ©΄ <? extends T>
λ₯Ό μ¬μ©(νμνμ
μΌλ‘ μ ν)νκ³ , μλΉμλΌλ©΄ <? super T>
λ₯Ό μ¬μ©(μμνμ
μΌλ‘ μ ν)νλΌ.choices
컬λ μ
μ T
νμ
μ κ°μ μμ°νκΈ°λ§ νλ(κ·Έλ¦¬κ³ λμ€μ μν΄ μ μ₯ν΄λλ€), T
λ₯Ό νμ₯νλ μμΌλμΉ΄λ νμ
μ μ¬μ©ν΄ μ μΈν΄μΌ ν¨.Chooser<Number>
μ μμ±μμ List<Integer>
λ₯Ό λκΈΈ μ μμ. public class Chooser<T> {
private final List<T> choiceList;
private final Random rnd = new Random();
// T μμ°μ 맀κ°λ³μμ μμΌλμΉ΄λ νμ
μ μ©
public Chooser(Collection<? extends T> choices) {
choiceList = new ArrayList<>(choices);
}
public T choose() {
return choiceList.get(rnd.nextInt(choiceList.size()));
}
public static void main(String[] args) {
List<Integer> intList = List.of(1, 2, 3, 4, 5, 6);
Chooser<Number> chooser = new Chooser<>(intList);
for (int i = 0; i < 10; i++) {
Number choice = chooser.choose();
System.out.println(choice);
}
}
}
popAll
μ dst
맀κ°λ³μλ StackμΌλ‘ λΆν° E
μΈμ€ν΄μ€λ₯Ό μλΉνλ―λ‘ dst
μ μ μ ν νμ
μ Collection<? super E> dst
μ. // E μλΉμ(consumer) 맀κ°λ³μμ μμΌλμΉ΄λ νμ
μ μ©
public void popAll(Collection<? super E> dst) {
while (!isEmpty())
dst.add(pop());
}
// swap λ©μλμ λ κ°μ§ μ μΈ
public static <E> void swap(List<E> list, int i, int j);
public static void swap(List<?> list, int i, int j);
βμ λ€λ¦κ³Ό κ°λ³μΈμλ₯Ό νΌμ©νλ©΄ νμ μμ μ±μ΄ κΉ¨μ§λ€β
...
)varargs
λ°°μ΄ λ§€κ°λ³μμ κ°μ μ μ₯νλ κ²μ μμ νμ§ μμ. // μ λ€λ¦κ³Ό varargsλ₯Ό νΌμ©νλ©΄ νμ
μμ μ±μ΄ κΉ¨μ§λ€!
static void dangerous(List<String>... stringLists) {
List<Integer> intList = List.of(42);
Object[] objects = stringLists;
objects[0] = intList; // ν μ€μΌ λ°μ
String s = stringLists[0].get(0); // ClassCastException
}
varargs
맀κ°λ³μλ₯Ό λ°λ λͺ¨λ λ©μλμ @SafeVarargs
λ₯Ό λ¬μλΌ.varargs
λ©μλλ μ λ μμ±ν΄μλ μλλ€λ λ»μ.varargs
λ©μλλ μμ ν¨varargs
맀κ°λ³μ λ°°μ΄μ μ무κ²λ μ μ₯νμ§ μλλ€.varargs
맀κ°λ³μλ₯Ό μμ νκ² μ¬μ©νλ λ©μλ μμ @SafeVarargs
static <T> List<T> flatten(List<? extends T>... lists) {
List<T> result = new ArrayList<>();
for (List<? extends T> list : lists)
result.addAll(list);
return result;
}
varargs
맀κ°λ³μλ₯Ό List
맀κ°λ³μλ‘ λ°κΏ μ μμvarargs
맀κ°λ³μλ₯Ό List
λ‘ λ체ν λ©μλ μμ static <T> List<T> flatten(List<List<? extends T>> lists) {
List<T> result = new ArrayList<>();
for (List<? extends T> list : lists)
result.addAll(list);
return result;
}
β컨ν μ΄λμμ 맀κ°λ³μν νμ μ μκ° μμμ μλΌλ©΄
νμ μμ μ΄μ’ 컨ν μ΄λ ν¨ν΄μ μ¬μ©νμβ
μ©μ΄ | μ€λͺ |
---|---|
class 리ν°λ΄ | String.class |
class 리ν°λ΄μ νμ | Class |
νμ ν ν° | λ©μλλ€μ΄ μ£Όκ³ λ°λ class 리ν°λ΄ |
public class Favorites {
public <T> void putFavorite(Class<T> type, T instance);
public <T> T getFavorite(Class<T> type);
}
cast
λ©μλλ νλ³ν μ°μ°μμ λμ λ²μ μ΄λ€.Class
κ°μ²΄κ° μλ €μ£Όλ νμ
μ μΈμ€ν΄μ€μΈμ§λ₯Ό κ²μ¬ν λ€μ, λ§λ€λ©΄ κ·Έ μΈμλ₯Ό κ·Έλλ‘ λ°ν, μλλ©΄ ClassCastException
μ λμ§.public class Favorites {
private Map<Class<?>, Object> favorites = new HashMap<>();
// λμ νλ³νμΌλ‘ λ°νμ νμ
μμ μ± ν보
public <T> void putFavorite(Class<T> type, T instance) {
favorites.put(Objects.requireNonNull(type), type.cast(instance));
}
public <T> T getFavorite(Class<T> type) {
return type.cast(favorites.get(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.printf("%s %x %s%n", favoriteString,
favoriteInteger, favoriteClass.getName());
}
Java cafebabe Favorites
λ₯Ό μΆλ ₯ν¨.getAnnotation
λ©μλpublic <T extends Annotation> T getAnnotation(Class<T> annotationType);