Generic
List<Integer> list = new ArrayList<>();
Map<String, Integer> map = new HashMap<>();
우리는 위의 예제와 같이 클래스 타입이 명시된 패턴을 자주 발견할 수 있다. 이걸 제네릭(Generic) 이라고 부르며, 제네릭 파라미터는 꺽쇠안에 포함하여 전달한다.
JAVA에서 제네릭이란?
- 파라미터 타입이나 리턴 타입에 대한 정의를 외부로 미룬다.
- 타입에 대해 유연성과 안정성을 확보한다.
- 런타임 환경에 아무런 영향이 없는 컴파일 시점의 전처리 기술이다.
제네릭을 왜 사용할까?
타입을 유연하게 처리하며, 잘못된 타입 사용으로 발생할 수 있는 런타임 타입 에러를 컴파일 과정에 검출한다.
제네릭을 사용하면 실수로 지정한 타입이 들어오는 경우 컴파일 시점에서 미리 예방할 수 있게 된다. 또한 클래스 외부에서 데이터 타입을 지정하기 때문에, 타입을 고려해서 이리저리 변환할 필요가 없다. 따라서 코드의 재사용성이 높아지고 전체 코드 관리가 용이해진다.
List v = new ArrayList();
v.add("test"); // A String that cannot be cast to an Integer
Integer i = (Integer)v.get(0); // Run time error
위와 같은 코드는 런타임 에러를 발생한다. List에 String을 저장하고 Integer로 타입 변환하는 오류가 런타임에 잡히는 것이다.
List<String> v = new ArrayList<String>();
v.add("test");
Integer i = (Integer)v.get(0); // (type error) compilation-time error
하지만 위와 같이 제네릭을 이용하면 컴파일 에러를 발생시켜 컴파일 시에 오류를 잡아낼 수 있다. 런타임 에러보다 컴파일 에러가 훨씬 디버깅이 쉽기 때문에 이점이 많다.
또한 제네릭에서는 <>안에서 데이터 타입을 자유롭게 설정할 수 있다. 특정 자료구조를 만들 때 Integer, String, Boolean 등 데이터 타입에 따라 다른 자료구조를 만든다면 매우 비효율적이다. 제네릭은 이러한 상황일 때 굉장히 효율적이다.
ArrayList list = new ArrayList(); //제네릭을 사용하지 않을경우
list.add("test");
String temp = (String) list.get(0); //타입변환이 필요함
ArrayList<String> list2 = new ArrayList(); //제네릭을 사용할 경우
list2.add("test");
temp = list2.get(0); //타입변환이 필요없음
제네릭에서 많이 사용되는 문자열들
이 문자열들은 개발자들이 암묵적으로 사용하는 코드일 뿐이지 사용자가 임의로 지정한 문자열을 넣어도 제네릭이 동작하는데에 아무런 영향을 미치지 않는다.
예시
제네릭 클래스
class ExampleGeneric<T> {
private T t;
public void setT(T t) {
this.t = t;
}
public T getT() {
return t;
}
}
클래스를 설계할 때 구체적인 타입을 명시하지 않고 타입 파라미터로 넣어두었다가 실제 설계한 클래스가 사용될 때 ExampleGeneric<String> YD = New ExampleGeneric<>(); 이런식으로 구체적인 타입을 지정하면서 사용하면 타입 변환을 최소화 할 수 있다.
제네릭 인터페이스
interface ExampleGeneric<T> {
T example();
}
class ExGeneric implements ExampleGeneric<String> {
// ExampleGeneric<String> <- String으로 넘어왔기 때문에 example()의 반환값이 String이여야만 한다.
@Override
public String example() {
return "YD";
}
}
멀티 타입 파라미터 사용
class ExMultiTypeGeneric<K, V> implements Map.Entry<K,V>{
private K key;
private V value;
@Override
public K getKey() {
return this.key;
}
@Override
public V getValue() {
return this.value;
}
@Override
public V setValue(V value) {
this.value = value;
return value;
}
}
타입은 두 개 이상의 멀티 타입 파라미터를 사용할 수 있고, 이 경우 각 타입 파라미터를 콤마로 구분한다.
제네릭 메소드
선언
// 제네릭 메소드 선언
// 매개 변수 타입: T
// 리턴 타입: Box<T>
public <T> Box<T> boxing(T t) {
Box<T> box = new Box<T>();
box.set(t);
return box;
}
먼저 리턴 타입(int, boolean, String, Box<T> 등등) 앞에 <T>와 같이 타입 파라미터를 기술한 다음,
매개 변수에 제네릭 타입 파라미터를 기입하면 된다.
호출
public class BoxingMethodExample {
public static void main(String[] args) {
Box<Integer> box1 = <Integer>boxing(100);
int intValue = box1.get();
Box<String> box2 = boxing("YD");
String strValue = box2.get();
}
}
메서드를 호출 할 때, <Integer> boxing(100); 처럼 타입 파라미터를 구체적으로 명시하여도 되고, 단순히 box(100);으로 작성하여도 타입 파라미터를 Integer로 추정하여 대입하게 된다.
제한된 타입 파라미터
// extends를 이용해 타입 제한
public static <T extends Number> int compare(T t1, T t2) {
double v1 = t1.doubleValue();
double v2 = t2.doubleValue();
return Double.compare(v1, v2);
}
위 제네릭 메소드에서 int 앞에 <T extends Number>라는 부분이 의미하는 바는
Number 클래스 또는 Number 클래스의 하위 타입 클래스만 사용할 수 있음을 의미한다.
그러므로 이 compare 제네릭 메소드에 String이나 기타 다른 타입이 삽입되는 것을 제한 할 수 있게 된다.
주의할 점
1. 상위 타입은 클래스뿐만 아니라 인터페이스도 가능하다. 하지만 그렇다고 extends를 implements라고 쓰진 않는다.
2. 제네릭 메소드의 중괄호 {} 안에서 타입 파라미터 변수로 가능한 것은 상위 타입의 멤버(필드, 메소드)로 제한한다.
- 즉 <T extends Number>라고 제네릭 메소드의 타입을 제한했다면, 메소드의 실행 부분에서 Number 타입의 필드와 메소드만 사용할 수 있다는 뜻이다. Integer에는 있고 Number에는 없는 필드나 메소드는 사용할 수 없다.
제네릭 와일드 카드
와일드카드는 물음표 ?로 표시하며 Java에서 unknown type이다. 와일드카드는 매개변수, 필드 또는 지역 변수의 유형 때론 반환 유형으로 다양한 상황에서 사용할 수 있다.
와일드카드 타입에는 총 세가지의 형태가 있으며 물음표(?)라는 키워드로 표현된다.
제네릭타입<?> : 타입 파라미터를 대치하는 것으로 모든 클래스나 인터페이스 타입이 올 수 있다.
제네릭타입<? extends 상위타입> : 와일드카드의 범위를 특정 객체의 하위 클래스만 올 수 있다.
제네릭타입<? super 하위타입> : 와일드카드의 범위를 특정 객체의 상위 클래스만 올 수 있다.
출처
https://coding-factory.tistory.com/573
'Java' 카테고리의 다른 글
람다(Lambda),스트림(Stream)이란? (3) | 2023.03.20 |
---|---|
[Java] final 키워드란? + static과의 궁합 (4) | 2023.02.24 |
오버로딩(Overloading),오버라이딩(Overriding)이란? + 차이점 (2) | 2023.02.12 |
Java Collection(컬렉션)이란? + 종류(Set,Map,List,Queue) (2) | 2023.02.09 |
GC(Garbage Collection)이란? + 대상,구조,예시 (3) | 2023.02.06 |