[Java] Generic
π‘ μ΄ κ²μκΈμ κΉμν κ°μ¬λμ μλ° κ°μλ₯Ό μκ°νλ©° νμ΅ν λ΄μ©μ μ€μν ν€μλ μ€μ¬μΌλ‘ μ 리ν κ°μΈ νμ΅ κΈ°λ‘μ λλ€. μ€μ§ κΈ°μ΅ λ³΅κΈ°λ₯Ό μν λͺ©μ μΌλ‘ μμ±λμμΌλ©°, λͺ¨λ λ΄μ©μ ν¬ν¨νμ§ μμΌλ―λ‘ νμ΅ μλ£λ‘λ μ ν©νμ§ μμ΅λλ€.
μμ μ μ₯λ³Έμ΄ λ μκ°λ κ²½μ°κ° μμ΄ demoλ‘ μ λ‘λ
Generic1
μ λ€λ¦μ ν΅μ¬μ μ¬μ©ν νμ
μ 미리 κ²°μ νμ§ μλλ€λ μ μ΄λ€.
ν΄λμ€ λ΄λΆμμ μ¬μ©νλ νμ
μ ν΄λμ€λ₯Ό μ μνλ μμ μ κ²°μ νλ κ²μ΄ μλλΌ μ€μ μ¬μ©νλ μμ± μμ μ νμ
μ κ²°μ νλ κ²μ΄λ€.
1
2
3
4
5
6
7
8
9
10
public class GenericBox<T> {
private T value;
public void set(T value) {
this.value = value;
}
public T get() {
return value;
}
}
νμ
λ§€κ°λ³μ: GenericBox<T> μμ T
νμ
μΈμ:
GenericBox<Integer> μμ Integer
GenericBox<String> μμ String
μ λ€λ¦ ν΄λμ€, μ λ€λ¦ μΈν°νμ΄μ€λ₯Ό λͺ¨λ ν©μ³μ μ λ€λ¦ νμ
μ΄λΌ νλ€.
GenericBox<T> λ₯Ό μ λ€λ¦ νμ
μ΄λΌ νλ€.
μ λ€λ¦ λͺ λͺ κ΄λ‘
μ£Όλ‘ μ¬μ©νλ ν€μλλ λ€μκ³Ό κ°λ€.
E - Element
K - Key
N - Number
T - Type
V - Value
S,U,V etc. - 2nd, 3rd, 4th types
νμ
μΈμλ‘ κΈ°λ³Ένμ μ¬μ©ν μ μλ€
μ λ€λ¦μ νμ
μΈμλ‘ κΈ°λ³Έν(int , double ..)μ μ¬μ©ν μ μλ€. λμ μ λνΌ ν΄λμ€(Integer , Double )λ₯Ό μ¬μ©
νλ©΄ λλ€.
1
GenericBox<Object> integerBox = new GenericBox<>();
Generic2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package generic.ex3;
import generic.animal.Animal;
public class AnimalHospitalV3<T extends Animal> {
private T animal;
public void set(T animal) {
this.animal = animal;
}
public void checkup() {
System.out.println(animal.getName());
System.out.println(animal.getSize());
animal.sound();
}
public T getBigger(T target) {
return animal.getSize() > target.getSize() ? animal : target;
}
}
μ¬κΈ°μ ν΅μ¬μ <T extends Animal> μ΄λ€.
νμ
λ§€κ°λ³μ T λ₯Ό Animal κ³Ό κ·Έ μμλ§ λ°μ μ μλλ‘ μ νμ λλ κ²μ΄λ€.
μ¦ T μ μνμ΄ Animal μ΄ λλ κ²μ΄λ€.
Generic Method
1
public static <T> T genericMethod(T t) { ... }
β ν΄λμ€ μ 체μ μ λ€λ¦μ΄ νμνμ§ μμ§λ§,
β νΉμ λ©μλμμλ§ νμ
μ μ μ°νκ² νκ³ μΆμ λ μ¬μ©ν¨
λ©μλ μμμ νμ
λ§€κ°λ³μ <T>λ₯Ό μ§μ μ μΈνκ³ , μ΄ νμ
μ νλΌλ―Έν°λ λ°ν νμ
μΌλ‘ μ¬μ©νλ λ©μλ
μ λ€λ¦ λ©μλλ ν΄λμ€ μ μ²΄κ° μλλΌ νΉμ λ©μλ λ¨μλ‘ μ λ€λ¦μ λμ ν λ μ¬μ©νλ€.
μ λ€λ¦ λ©μλμ ν΅μ¬μ λ©μλλ₯Ό νΈμΆνλ μμ μ νμ μΈμλ₯Ό μ λ¬ν΄μ νμ μ μ§μ νλ κ²μ΄λ€. λ°λΌμ νμ μ μ§μ νλ©΄μ λ©μλλ₯Ό νΈμΆνλ€.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package generic.ex4;
public class GenericMethod {
// 1. κ·Έλ₯ Objectλ‘ λ°λ μΌλ° λ©μλ
public static Object objMethod (Object obj) {
System.out.println("object print: " + obj);
return obj;
}
// 2. μ λ€λ¦ λ©μλ (νμ
νλΌλ―Έν° T)
public static <T> T genericMethod (T t) {
System.out.println("generic print: " + t);
return t;
}
// 3. μ λ€λ¦ + νμ
μ ν (Tλ Number λλ κ·Έ νμ ν΄λμ€λ§)
public static <T extends Number> T numberMethod (T t) {
System.out.println("bound print: " + t);
return t;
}
}
Generic Method - static, instance method
1
2
3
4
class Box<T> { //μ λ€λ¦ νμ
static <V> V staticMethod2(V t) {} //static λ©μλμ μ λ€λ¦ λ©μλ λμ
<Z> Z instanceMethod2(Z z) {} //μΈμ€ν΄μ€ λ©μλμ μ λ€λ¦ λ©μλ λμ
κ°λ₯
}
static λ©μλλ ν΄λμ€κ° λ‘λλ λ λ©λͺ¨λ¦¬μ μ¬λΌμ€κ³ ,
μ΄ μμ μ ν΄λμ€μ μ λ€λ¦ νμ
Tκ° μμ§ κ²°μ λμ§ μμκΈ° λλ¬Έμ,
λ©μλ μμμ <T> λ₯Ό μ§μ μ μΈνλ©΄ ν΄λμ€μ μκ΄μμ΄ λ©μλ νΈμΆ μμ μ νμ
μ μμμ μ ν μ μμ.
<T>λ νμ
λ§€κ°λ³μ μ μΈ
1
2
3
`<T>`λ βνμ
μ λμ€μ μ νμβλ λ»μ΄κ³ ,
ν΄λμ€μμ μ°λ©΄ βκ°μ²΄ λ§λ€ λ μ νκ³ β,
λ©μλμμ μ°λ©΄ βλ©μλ νΈμΆν λ μ νλ€." κ·Έ λ€μ μ€λ `T`λ κ·Έ μ μΈν νμ
μ λ¦¬ν΄ νμ
μΌλ‘ μ°κ² λ€λ λ» λ§€κ°λ³μμ `(T t)`λ κ·Έ νμ
μ κ°μ λ°μ μ°κ² λ€λ λ»
Generic Method - Type Parameter Bound
1
public static <T extends Number> T numberMethod(T t) {}
** Generic Type, Generic Method **
static methodλ ν΄λμ€μ Tλ₯Ό μ μ μκΈ° λλ¬Έμ λ°λμ <T>λ‘ μ λ€λ¦ λ©μλ μ μΈμ ν΄μΌ νκ³ ,
Γ¬nstance methodλ μ΄λ―Έ ν΄λμ€μ μ λ€λ¦ νμ
μ΄ μ ν΄μ§ μνλΌμ ν΄λμ€μ Tλ , λ©μλμ Tλ λ λ€ μ¬μ© κ°λ₯νλ€!
Generic Type Generic Method μ μ°μ μμ
π±
μ€νλ§μ λΉ λ₯΄κ² λ°°μ°κΈ° μν΄μ μ€κΈ1νΈ κ°μμ μΌλΆλ₯Ό skip νλλ ν·κ°λ¦¬λ λΆλΆμ΄ μκ²Όλ€.
μ°μ°νκ² λμ΄κ°λκ±Έ λͺ»ν΄μ λ°λ‘ 곡λΆν΄λ³΄κΈ°λ‘ ~..
getClass().getName() μμμ getName() κ³Ό animal.getName() μμμ getName() μ μ°¨μ΄μ μ λͺ¨λ₯΄κ² λ€λ λ¬Έμ μλ€.
** getClass() **
1
public final Class<?> getClass()
μ΄κ±΄ μλ°μμ λͺ¨λ κ°μ²΄κ° μ¬μ©ν μ μλ λ©μλκ³ , Object ν΄λμ€μ μ μλμ΄ μλ€.
1
2
λ°νκ°
Class<?>
μ¦, μλ°μ βν΄λμ€λ₯Ό νννλβ κ°μ²΄λ₯Ό λ°ννλ€.
μ΄ κ°μ²΄λ μλ° λ΄λΆμμ βν΄λμ€ μ체βλ₯Ό μ€λͺ
νλ λ©ν μ 보λ₯Ό λ΄κ³ μλ€.
1
2
3
4
5
6
String s = "hello";
System.out.println(s.getClass()); // class java.lang.String
System.out.println(s.getClass().getName()); // java.lang.String
System.out.println(s.getClass().getSimpleName()); // String
System.out.println(s.getClass().getSuperclass()); // class java.lang.Object
s.getClass()λ ν΄λμ€ μ체λ₯Ό μ€λͺ
νλ κ°μ²΄κ³ ,
s.getClass().getName()μ κ·Έ ν΄λμ€μ μ΄λ¦λ§ λ¬Έμμ΄λ‘ κΊΌλΈ κ²μ΄λ€.
getClass().getName() μμμ getName()
μ΄ κ²½μ°μ getName()μ μ§μ§ λ΄μ₯ API λ©μλ.
getName() β Class ν΄λμ€μ λ©μλ (ν΄λμ€ μ΄λ¦μ λ¬Έμμ΄λ‘ μλ €μ€).
animal.getName() μμμ getName()
λ΄κ° Animal ν΄λμ€ μμμ μ§μ λ§λ μΌλ° λ©μλ
π± getName()λ§ μ°λ©΄ μ λκ³ , κΌ getClass().getName()μ²λΌ μ¨μΌ νλ?
getName()μ ν΄λμ€(Class κ°μ²΄)μ μ μλ λ©μλμ§, λ§λ κ°μ²΄(μ: String, Animal λ±) μ체μλ getName()μ΄λΌλ λ©μλκ° λ°λμ μλ κ² μλ
κ·Έλμ getName()μ μ°λ €λ©΄ λ¨Όμ getClass()λ₯Ό ν΅ν΄ βν΄λμ€λ₯Ό μ€λͺ νλ κ°μ²΄βλ₯Ό κ°μ ΈμμΌ ν¨.
1
s.getClass().getName()
βs κ°μ²΄μ ν΄λμ€κ° λλ? β κ·Έ ν΄λμ€ κ°μ²΄μμ μ΄λ¦μ΄ λλ?β
π± Animal ν΄λμ€ λ΄λΆμ getName() μ΄ μ€λ²λΌμ΄λκ° μλ μ΄μ
getClass().getName()μ getName()μ Class ν΄λμ€μ λ΄μ₯ λ©μλ,
animal.getName()μ getName()μ λ€κ° Animal ν΄λμ€μμ λ§λ μΌλ° λ©μλ μ΄λ€.
μ΄λ¦μ΄ κ°μ λΏ μμ ν λ€λ₯Έ μ‘΄μ¬μ΄κΈ° λλ¬Έμ ( μμ κ΄κ³λ μκ³ , λ€λ₯Έ ν΄λμ€μ μμΌλ―λ‘ μ ν κ΄λ ¨μ΄ μμ ) μ€λ²λΌμ΄λ μ ν΄λΉλμ§ μλλ€.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package generic.animal;
public class Animal {
private String name;
private int size;
public Animal(String name, int size) {
this.name = name;
this.size = size;
}
public String getName() {
return name;
}
public int getSize() {
return size;
}
public void sound() {
System.out.println("λλ¬Ό μΈμ μ리");
}
@Override
public String toString() {
return "Animal{" +
"name='" + name + '\'' +
", size=" + size +
'}';
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package generic.ex4;
import generic.animal.Animal;
public class ComplexBox<T extends Animal> {
private T animal;
public void set(T animal) {
this.animal = animal;
}
public <T> T printAndReturn(T t) {
System.out.println("animal.className: " + animal.getClass().getName());
System.out.println("t.className: " + t.getClass().getName());
// t.getName(); // νΈμΆ λΆκ° λ©μλλ <T> νμ
μ΄λ€. <T extends Animal> νμ
μ΄ μλλ€.
return t;
}
}
ν΄λμ€μ <T>μ λ©μλμ <T>λ μμ ν λ€λ₯Έ Tλ€.
μ λ€λ¦ νμ
(T) μ΄ ν΄λμ€μ μ΄λ―Έ μμ΄λ,
λ©μλμμ <T>λ₯Ό λ€μ μ μΈνλ©΄ κ·Έ λ©μλ μμμλ κ·Έκ² μ°μ μ μ©λλ€.
κ·Έλμ λ©μλμ <T>λ ν΄λμ€μ Tμ μμ λ³κ°μ΄λ©°, μ΄λ¦μ΄ κ°μλ μκΈ° μμμμλ λ©μλμ Tκ° μ°μ μ΄λ€.