Generics
Generics 란
Generics are a facility of generic programming that were added to the Java programming language in 2004 within version J2SE 5.0. They were designed to extend Java's type system to allow "a type or method to operate on objects of various types while providing compile-time type safety". - Wiki
Generics add stability to your code by making more of your bugs detectable at compile time. - Oracle Java Docs
Generic은 클래스 내부에서 사용할 데이터 타입을 외부에서 지정하는 기법 - 생활코딩
Wiki, Oracle Java docs, 생활코딩을 보면 위와 같이 정의를 내린다.
한 마디로, 인스턴스 생성할 때 타입을 지정할 수 있다.
이를 이용하여 컴파일 타임에서 에러를 잡을 수 있다.
메서드에도 적용할 수 있다.
어떤 상황에서 사용할까?
1. Compile time에서 강한 타입 체크를 할 수 있다.
- 실행시 타입 에러가 나는 것보다 컴파일 시에 미리 타입을 체크해 에러를 사전에 방지
2. 타입 변환(Casting)을 제거한다.
- 비제네릭 코드는 불필요한 타입 변환을 하기 때문에 프로그램 성능에 악영향을 끼친다.
List list = new ArrayList();
list.add("hello");
String str = (String) list.get(0);
// 내부적으로는 타입을 Object로 추론하고 String 타입으로 변환하기 위해 강제 형변환이 필요하다.
만약, 제네릭 타입으로 작성하지 않은 코드에서 Object로 했을 때도 마찬가지이다.
List<String> list2 = new ArrayList<>();
list2.add("hello");
String str2 = list.get(0); // 타입타입변환이 필요없음
3. 제네릭 타입(class, interface)
- 제네릭 타입은 타입을 파라미터로 가지는 클래스와 인터페이스를 말한다.
클래스 또는 인터페이스 뒤에 "<>"(Diamond Operator)가 붙고 사이에 타입 파라미터가 위치한다.
public class 클래스<T> {...}
public interface 인터페이스<T> {...}
타입파라미터는 일반적으로 대문자 알파벳 한 글자로 표현한다.
아무 문자를 넣어도 동작하지만 타입 파라미터도 컨벤션이 존재한다.
4. 멀티 타입 파라미터(class<K, V, ...>, interface<K, V, ...)
- 제네릭 타입은 두 개 이상의 멀티 파라미터를 이용할 수 있다. 타입 파라미터는 콤마로 구분한다.
public class Entry implements Map.Entry<K,V> {
private K key;
private V value;
public Entry(K key, V value) {
...
}
...
}
5. 제네릭 메서드(<T, R> R 메서드이름(T t))
- 제네릭 메서드는 매개타입과 리턴타입으로 타입 파라미터를 갖는 메서드를 의미한다.
- 제니릭 메서르르 선언하는 방법은 리턴 타입 앞에 "<>"기호를 추가하고 타입 파라미터를 기술한 다음, 리턴 타입과 매개 타입으로 타입 파라미터를 사용하면 된다.
public <타입파라미터, ...> 리턴타입 메서드명(매개변수, ...) { ... }
public <T> Test<T> testMethod(T t) { ... }
// 호출 방법
Test<Integer> test = <Integer>testMethod(10); // 명시적으로 Integer를 지정
Test<Integer> test2 = testMethod(10); // Integer로 추정(컴파일러가 전달인자를 보고 타입 추정)
6. 제한된 타입 파라미터(<T extends 상위타입>)
상속을 통해 T의 타입을 제한할 수 있는데
T는 Info클래스이거나 Info클래스의 하위 클래스로 제한된다.
class Person <T extends Info> {
...
}
또는, 제네릭 메서드도 마찬가지이다.
public <T extends Number> int compare(T t1, T t2) {
double v1 = t1.doubleValue();
...
}
7. 와일드카드 타입(<?>, <? extends ...>, <? super ...>)
- 제네릭타입<?> : 제한 없음(모든 클래스나 인터페이스 타입이 올 수 있다.)
- 제네릭타입<? extends 상위타입> : 상위타입 이하의 타입으로 제한
- 제네릭타입<? super 하위타입> : 하위타입 이상의 타입으로 제한
Generics를 사용하면서 중복 코드제거(Type을 외부에 맡김으로써)와 안전성을 추구(Compile type시 에러 체크)할 수 있게 된다.
medium.com/@joongwon/java-java의-generics-604b562530b3
https://docs.oracle.com/javase/tutorial/java/generics/index.html
https://opentutorials.org/course/1223/6237
https://cornswrold.tistory.com/180
https://woowacourse.github.io/javable/post/2020-11-09-generics-basic/