요약
본 포스트는 오라클 자바 튜토리얼 제네릭 부분을 공부한 내용을 적은 포스트이다.
JDK 8 기반으로 작성됐다.
https://docs.oracle.com/javase/tutorial/java/generics/why.html
제네릭은 왜 쓰는가
제네릭은 클래스, 인터페이스, 메서드를 선언할 때 타입(클래스, 인터페이스)도 매개변수로 만들 수 있다.
전통적인 매개변수와 마찬가지로 타입 매개변수도 다양한 인풋을 받을 수 있게한다.
타입 체크를 컴파일 타임에 한다.
1
2
3
4
5
6
7
8
9
10//정수를 리스트에 담아서 사용하려고 했는데 실수로 문자열을 넣는 상황
//제네릭이 아닌 경우
List list = new ArrayList();
list.add("hello"); //컴파일 에러가 발생하지 않는다.
int hello = (int) list.get(0); //나중에 실행하면 여기서 ClassCastException이 발생한다.
//제네릭인 경우
List<Integer> genericList = new ArrayList<>();
genericList.add("hello"); //컴파일 에러캐스팅 할 필요 없어진다.
1
2
3
4
5
6
7
8//제네릭 없는 경우
List list = new ArrayList();
list.add("하이");
String hi = (String) list.get(0); //제네릭을 전달하지 않으면 Object를 반환
List<String> stringList = new ArrayList<String>();
stringList.add("하이");
String hello = list.get(0);
제네릭 간단하게 사용해보자
아무 타입이나 저장할 수 있는 Box 클래스를 구현하고자 한다.
제네릭 없이 구현하자면 다음과 같을 것 이다.
1 | class ObjectBox { |
이런 경우, get할 때마다 casting을 해줘야 된다.
그리고 담겨진 내용물을 잘못 파악해 casting해도 컴파일 타임에 알 수 없고 런타임 때 ClassCastException이 발생한다.
제네릭을 사용
1 | class GenericBox<T> { |
제네릭을 사용하면 캐스팅이 필요없고 casting도 필요 없다.
타입 파라미터 네이밍 컨벤션
위에서 T는 타입 파라미터라고 한다.
- E - Element
- K - Key
- N - Number
- T - Type
- V - Value
- S, U, V - 2, 3, 4번째 타입
이렇게 지칭한다.
제네릭 타입 인보킹과 인스턴스화
제네릭 타입 인보킹은 위에서 적은 T와 같은 매개변수를 우리가 의도한 실제 타입으로 변환하는 행위를 말한다.
1 | Box<Integer> integerBox; |
참조변수를 통해 타입 인보킹을 해줄 수 있다.
이때 조심해야 할 것은 T는 타입 매개변수이고, Integer는 타입인자이다. 이 두가지는 다르다.
제네릭을 사용하는 클래스를 인스턴스화하려면 다음과 같다.
1 | Box<Integer> integerBox = new Box<Integer>(); |