학습할 것
- 제네릭 사용법
- 제네릭 주요 개념 (바운디드 타입, 와일드 카드)
- 제네릭 메소드 만들기
- Erasure
Generic
넓게보면 숨쉬듯 생겨나는 버그를 어느정도 방지해주는 역할을 하게 됩니다.
이런 행위가 가능한 이유는 자바를 사용하면서 데이터의 타입 때문에 생기는 버그에 대해 강력하게 방지할 수 있습니다. 이는 미리 받을 데이터의 타입을 확인하기 때문에 가능합니다.
제너릭을 사용하는 이유로 oracle에선 3가지를 공유하고 있습니다.
- 컴파일 타임에 더욱 강력한 유형 검사
런타임전에 컴파일 단계에서 오류를 발생시켜 런타임에서의 오류를 감소 시킵니다.
- cast 제거
그동안 타입을 변환할때 casting을 사용했습니다.
List list = new ArrayList();
list.add("hello");
String s = (String) list.get(0);
하지만 이제 더이상 casting을 할 필요가 없습니다.
List<String> list = new ArrayList<String>();
list.add("hello");
String s = list.get(0); // no cast
- 프로그래머가 알고리즘을 구현할 수 있도록 허용
프로그래머는 제너릭을 사용해 다양한 유형의 안전하고 읽기 쉬운 알고리즘을 구현할 수 있습니다.
제네릭 사용법
사용법
// https://docs.oracle.com/javase/tutorial/java/generics/types.html
/**
* Generic version of the Box class.
* @param <T> the type of the value being boxed
*/
public class Box<T> {
// T stands for "Type"
private T t;
public void set(T t) { this.t = t; }
public T get() { return t; }
}
제너릭은 형태를 가지고 있으며 아래 코드와 같은 방식으로도 자주 사용됩니다.
Box <Integer> integerBox;
명명규칙
E | Element |
K | Key |
N | Number |
T | Type |
V | Value |
S, U, V, ...etc | 2nd, 3rd, 4th types |
개발자의 의도에 따라 명명규칙을 지키지 않아도 상관없지만, 더욱 가독성 좋은 코드를 위해 명명 규칙에 따라 코드를 작성하는 것을 권장하고 있습니다.
제네릭 주요 개념 (바운디드 타입, 와일드 카드)
- Bounded Type
제네릭 타입의 범위를 제한하는 경우가 생길수 있습니다. 그럴 경우를 대비하여 만들어진게 Bounded Type입니다.
public class Box<T> {
private T t;
public void set(T t) {
this.t = t;
}
public T get() {
return t;
}
public <U extends Number> void inspect(U u){
System.out.println("T: " + t.getClass().getName());
System.out.println("U: " + u.getClass().getName());
}
public static void main(String[] args) {
Box<Integer> integerBox = new Box<Integer>();
integerBox.set(new Integer(10));
integerBox.inspect("some text"); // error: this is still String!
}
}
- Wildcard
와일드 카드는 제네릭으로 구현된 메소드에 어떤 타입이 와도 상관 없는 경우, 즉 타입이 애매할때 사용할 수 있다고 하는데 아직까진 크게 와닿지 않습니다. .
제네릭 메소드 만들기
메소드에 <K, V>로 제네릭을 선언할 수 있습니다.
public class Util {
public static <K, V> boolean compare(Pair<K, V> p1, Pair<K, V> p2) {
return p1.getKey().equals(p2.getKey()) &&
p1.getValue().equals(p2.getValue());
}
}
Erasure
Type Erasure는 살면서 처음봤습니다. 컴파일 단계에서만 제네릭을 적용하고 런타임 단계에서는 제네릭을 적용하지 않는것 처럼 보이는데 실제로 실습해봐야 할것 같 습니다.
Pair<Integer, String> p1 = new Pair<>(1, "apple");
Pair<Integer, String> p2 = new Pair<>(2, "pear");
boolean same = Util.<Integer, String>compare(p1, p2);
이 코드가 런타임에서는
Pair<Integer, String> p1 = new Pair<>(1, "apple");
Pair<Integer, String> p2 = new Pair<>(2, "pear");
boolean same = Util.compare(p1, p2);
로 변경된다고 합니다.
'IT 이야기 > Java' 카테고리의 다른 글
JPA Default value 적용 - @DynamicInsert (0) | 2021.07.20 |
---|---|
POJO Class (0) | 2021.06.28 |
[Java Study] 13일차 I/O [input/output] (0) | 2021.02.13 |
[Java Study] 12일차 Annotation (0) | 2021.02.04 |
[Java Study] 11일차 Enum (0) | 2021.01.26 |
댓글