IT 개발노트
제네릭스(Generics) 본문
1. 제네릭스(Generics)
1.1 제네릭스란?
: 제네릭스는 다양한 타입의 객체들을 다루는 메서드나 컬렉션 클래스에 컴파일 시의 타입 체크(compile-time type check)를 해주는 기능이다.
객체의 타입을 컴파일 시에 체크하기 때문에 객체의 타입 안정성을 높이고 형변환의 번거로움이 줄어든다.
- 쉽게말해서 컬렉션 클래스가 다룰 객체를 미리 명시해줌으로써 형변환을 하지 않고 사용하는 것이다.
1.1.1 제네릭스의 장점
- 타입 안정성을 제공한다.
- 타입체크와 형변환을 생략할 수 있으므로 코드가 간결해 진다.
: 다룰 객체의 타입을 미리 명시해줌으로써 번거로운 형변환을 줄여준다.
1.2 제네릭 사용예시
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | package Java.sungju.JavaProject; import java.util.ArrayList; public class JavaProject { public static void main(String[] args) { // <String> 제네릭스를 사용한 경우 ArrayList<String> mStringList = new ArrayList<String>(); mStringList.add("안녕하세요"); mStringList.add("3"); for(String s : mStringList) { System.out.println(s); } // <Integer> 제네릭스를 사용한 경우 ArrayList<Integer> mIntegerList = new ArrayList<Integer>(); mIntegerList.add(1); mIntegerList.add(2); for(Integer i : mIntegerList) { System.out.println(i); } // <Class명> 제네릭스를 사용한 경우 ArrayList<Tv> mTvList = new ArrayList<Tv>(); { mTvList.add(new Tv()); mTvList.add(new Tv("New Tv")); for(Tv t : mTvList) { System.out.println(t); } // < 제네릭스를 사용하지 않은 경우 > // 모든타입을 "add(Object)" Object형으로 List에 Add를 // 시켜 주므로, List에서 자료를 꺼내올때는 각각에 맞는 형변환을 // 꼭 해주어야 하기 때문에 번거 롭다. ArrayList mOriginalList = new ArrayList(); mOriginalList.add(1); mOriginalList.add("string"); mOriginalList.add(new Tv("original")); int a = (Integer) mOriginalList.get(0); String b = (String) mOriginalList.get(1); Tv c = (Tv) mOriginalList.get(2); } } } // Tv Class class Tv { private String caption; public Tv() { this("Tv Class 입니다."); } public Tv(String caption) { this.caption = caption; } public String toString() { return caption; } } |
: 위의 예제처럼 상황에 맞는 <제네릭스>를 선택해서 사용하면 된다.
int대신 Integer를 사용한 이유는 <제네릭스>를 선언할 수 있는 타입이 객체 타입이기 때문이다.
int같은 경우에는 기본자료형이기 때문에 <제네릭스>타입 자료에는 들어갈수가 없다.
그래서 자료형을 객체화시킨 wrapper클래스를 사용해서 사용한다.
wrapper클래스란 기본형변수들에 기능을 좀더 추가해서 객체화 시킨 클래스이다.
1.3 제네릭의 다형성
: 다형성이란 '부모의 참조변수로 자식 객체를 참조할수 있는 것'이다.
예시
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | package Java.sungju.JavaProject; import java.util.ArrayList; public class JavaProject { public static void main(String[] args) { // product클래스의 자손객체들을 저장할 수 있는 ArrayList를 생성 ArrayList<Product> list = new ArrayList<Product>(); list.add(new Product()); list.add(new Vcr()); list.add(new Audio()); // 자손의 객체를 꺼내 올때는 형변환이 필요하다. Product p = list.get(0); Vcr v = (Vcr)list.get(1); } } class Product{}; class Vcr extends Product{}; class Audio extends Product{}; |
ArrayList가 Product타입의 객체를 저장하도록 지정하면, 이들의 자손인 Vcr과 Audio타입의 객체도 저장할 수 있다. 다만 꺼내올 때 원래의 타입으로 형변환 해야 한다.
1 2 3 | // 자손의 객체를 꺼내 올때는 형변환이 필요하다. Product p = list.get(0); Vcr v = (Vcr)list.get(1); |
하지만 매개변수 타입의 ArrayList<Product>로 선언된 경우, 이 메서드의 매개변수로 ArrayList<Product>타입의 객체만 사용할 수 있다. 그렇지 않으면 컴파일 에러가 발생한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | package Java.sungju.JavaProject; import java.util.ArrayList; public class JavaProject { public static void main(String[] args) { ArrayList<Product> pArrayList = new ArrayList<Product>(); ArrayList<Vcr> vArrayList = new ArrayList<Vcr>(); printAll(pArrayList); // 컴파일 에러 printAll(vArrayList); } public static void printAll(ArrayList<Product> list) { for(Product p : list) { System.out.println(p); } } } class Product{}; class Vcr extends Product{}; class Audio extends Product{}; |
: 매겨변수의 다형성을 이용하기 위해서는 와일드 카드 '?'를 사용하면 된다.
보통 제네릭에서는 단 하나의 타입을 지정하지만 와일드 카드는 하나 이상의 타입을 지정하는것을 가능하게 해준다.
1.3.1 와일드카드 사용방법
: 만일 Product가 클래스가 아닌 인터페이스라 할지라도 키워드로 'implements'를 사용하지 않고 클래스와 동일하게 'extends'를 사용한다는 것에 주의하기
1 2 3 4 5 6 | // Product 또는 그 자손들이 담긴 ArrayList를 매개변수로 받는 메서드 public static void printAll(ArrayList<? extends Product> list) { for(Product p : list) { System.out.println(p); } } |
와일드 카드는 (ArrayList<? extends Product> list)말고도 또 다른 형식으로도 쓰인다.
바로 아래의 메서드 형식이다.
1 2 3 4 5 6 | // 와일드 카드의 또다른 형식 public static <T extends Product> void printAll(ArrayList<T> list) { for(Product p : list) { System.out.println(p); } } |
와일드 카드를 쓸때는 Product를 상속받은 클래스(Vcr, Audio)를 <제네릭>으로 사용하는 ArrayList를 생성한 후 메서드에 넣어 주면 된다.
<? extends T> : 와일드 카드의 상한 제한. T와 그 자손들만 가능
<? super T> : 와일드 카드의 하한 제한. T와 그 조상들만 가능
<?> : 제한 없음. 모든 타입이 가능. <? extends Object>와 동일
'기초튼튼 > JAVA' 카테고리의 다른 글
프로세스 호출 예제 (0) | 2019.02.19 |
---|---|
숫자맞추기 게임 (0) | 2019.02.18 |
스레드 (0) | 2019.02.10 |
JAVA 입출력(I/O) 알아보기 (0) | 2019.02.10 |
컬렉션이란 (0) | 2019.02.07 |