-
Java - 제네릭(Generics)Java/java study 2022. 4. 3. 22:26728x90반응형
제네릭(Generics)
- 제네릭 사용법
- 제네릭 - 바운디드 타입
- 제네릭 - 와일드카드
- 제네릭 메서드
제네릭(Generics)란?
지네릭스는 다양한 타입의 객체를 다루는 메서드나 컬렉션 클래스에 컴파일 시의 타입 체크를 해주는 기능이다. 객체의 타입을 컴파일 시에 체크하기 때문에 객체의 타입 안정성을 높이고 형 변환의 번거로움을 줄일 수 있다.
- 타입 안정성
의도하지 않은 타입의 객체가 저장되는 것을 막고, 저장된 객체를 꺼내올 때 원래의 타입과 다른 타입으로 잘못 형 변환되어 발생할 수 있는 오류를 줄여준다.
- 제네릭을 사용하는 이유
- 제네릭 타입을 사용함으로써 잘못된 타입이 사용될 수 있는 문제를 컴파일 과정에서 제거할 수 있기 때문
- 자바 컴파일러는 코드에서 잘못 사용된 타입 때문에 발생하는 문제점을 제거하기 위해 제네릭 코드에 대해 강한 타입 체크를 한다.
- 실행 시 타입 에러가 나는 것보다 컴파일 시에 미리 타입을 강하게 체크하여 에러를 사전에 방지할 수 있다.
- 제네릭 코드를 사용하면 타입을 국한하기 때문에 요소를 찾아올 때 타입 변환을 할 필요가 없어 프로그램 성능이 향상되는 효과를 얻을 수 있다.
제네릭 사용법
- 제네릭 클래스 선언
public class Box<T> { private T type; public void set(T type) { this.type = type } public T get() { return type; } }
- T를 타입 변수(Type variable) 이라 한다.
- 타입 변수는 상황에 맞는 의미 있는 문자를 선택하여 사용할 수 있다.
- T : Type, E : Element, K : Key, V : Value - 과거에는 Object로 다양한 종류의 타입을 다룰 때 사용했지만 타입 체크 시 문제가 발생했다.
- 제네릭 클래스 사용
Box<String> box = new Box(); // 타입 변수에 String을 전달하였으므로 아래와 같다. public class Box { private String type; public void set(String type) { this.type = type } public String get() { return type; } } Box<int> box = new box(); // 타입 변수에 int를 전달하였으므로 아래와 같다. public class Box { private int type; public void set(int type) { this.type = type } public int get() { return type; } }
- 지네릭스의 제한
- 모든 객체에 대해 동일하게 동작해야 하는 static멤버에 타입 변수 T를 사용할 수 없다.
- 지네릭 타입의 배열을 생성할 수 없다.(컴파일러가 컴파일 시점에 타입 T 가 무엇인지 알아야 하기 때문)
제네릭 주요 개념 - 바운디드 타입(Bounded Type)
- 바운디드 타입은 특정 타입의 서브 타입으로 제한한다.
- 클래스나 인터페이스 설계할 때 가장 흔하게 사용할 정도로 많이 볼 수 있는 개념이다.
public class Box<T extends S> { ... }
- 타입 변수 T는 S의 서브 타입만 허용한다.
제네릭 주요 개념 - 와일드카드(WildCard)
- Unbounded WildCard
- ? 와 같은 형태로 물음표만 가지고 정의한다.( ex. List<?> )
- 내부적으로 Object로 정의되어 있기 때문에 모든 타입의 인자를 받을 수 있다.
- 타입 파라미터에 의존하지 않는 메서드만을 사용하거나 Object 메서드에서 제공하는 기능으로
충분한 경우 사용한다. - Object 클래스에서 제공되는 기능을 이용하여 구현하는 메서드에서 사용
- 타입 파라미터에 의존적이지 않는 일반 클래스의 메서드를 사용하는 경우에 사용
ex) List, clear, List, size 등
- Upper Bounded Wildcard
- 특정 클래스의 자식 클래스만을 인자로 받을 때 사용한다.
- 사용할 수 있는 기능은 특정 클래스에서 정의된 기능만 사용할 수 있다.
ex) List<? extends Skill>
- Lower Bounded Wildcard
- 특정 클래스의 부모 클래스만을 인자로 받을 수 있다.
ex) List<? supper Skill>
지네릭 메서드
- 메서드 선언부에 지네릭 타입이 선언된 메서드를 지네릭 메서드라 한다.
- static 멤버에는 타입 매개변수를 사용할 수 없지만, 메서드에는 사용이 가능하다.
- 지네릭 타입의 선언 위치는 반환 타입 바로 앞이다.
static <T> void sort(List<T> list, Comparator<? super T> c)
- 제네릭 클래스에 정의된 타입 매개변수와 제네릭 메서드에 정의된 타입 매개변수는
서로 다른 타입 변수다.(같은 타입 문자 T를 사용해도 같은 타입 변수가 아니다)
class FruitBox<T>{ ... static <T> void sort(List<T> list, Compatrator<? super T> c){ ... } }
예시
public static void printAll( ArrayList<? extends Product> list, ArrayList<? extends Product> list2){ for(Unit u : list){ System.out.println(u); } } // 지네릭 메서드로 변경 public static void printAll( ArrayList<? extends Product> list, ArrayList<? extends Product> list2){ for(Unit u : list){ System.out.println(u); } }
728x90반응형'Java > java study' 카테고리의 다른 글
Java - 람다식 (0) 2022.04.10 Java - Input과 Output(I/O) (0) 2022.03.27 Java - 애노테이션(annotation) (0) 2022.03.06 Java - enum이란 (0) 2022.02.27 Java - Thread (0) 2022.02.20