#What
API 문서들을 보면 Generic 표현이 널려있는 것을 볼 수 있습니다.
보다 정확한 도큐먼트 이해를 위해 Generic 표현을 정리해 봅시다.
Generic이란?
- 클래스, 인터페이스, 메소드 내부에서 사용할 데이터 타입을 외부에서 지정해서 사용 하는 방법
- 사전적 의미 : <포괄적인, 총칭[통칭]의>
장점
- Casting, 즉 타입 변환 할 필요 없음 (불필요한 성능 소모X)
- 컴파일 시 잘못된 타입 사용에 대한 체크가 가능(타입 제한이 되므로)
#예제 1 - 어떻게 사용하는가?
JAVA
Kotlin
#예제 2 - 클래스에 Generic 적용 하기
Student 클래스에 'id'필드의 타입을 int, String 등 2가지 이상의 타입으로 받고 싶을 경우
Generic 사용 X
public class Student {
private Object id;
public Object getId() {
return id;
}
public void setId(Object id) {
this.id = id;
}
}
public void genericTest() {
Student student = new Student();
student.setId(1);//형변환
int idInt = (int) student.getId(); //형변환
Student student2 = new Student();
student2.setId("1"); //형변환
String idStr = (String) student2.getId(); // 형변환
}
generic을 사용하지 않을 경우 set 할 때도( 타입 -> Object), get 할 때도(Object -> 타입 ) 타입변환이 일어난다.
casting의 불편함을 떠나서 퍼포먼스적으로도 좋지 못하다.
Generic 사용 O
public class Student<T> {
private T id;
public T getId() {
return id;
}
public void setId(T id) {
this.id = id;
}
}
public void genericTest() {
Student<Integer> student = new Student<>();
student.setId(1);
int idInt = student.getId();
Student<String> student2 = new Student();
student2.setId("1");
String idStr = student2.getId();
}
규칙 : 클래스 선언 뒤에 '타입 파라미터'를 명시 <T>
generic을 사용하게 된다면 set/get 시 타입 변환 없이 사용할 수 있다
*이 처럼 타입을(<T>) 파라미터로 가지는 클래스와 인터페이스를 '제네릭 타입' 이라고 한다
#예제 3 - 함수의 파라미터와 리턴 타입에 Generic 적용 하기
배열로 인자들을 받아서 LIST로 변환 해주는 함수... 예제를 위한 예제를 보자
//리턴 타입 = List<K>
//파람 타입 = K
public <K> List<K> getArrayList(K... element) {
List<K> list = new ArrayList<>(Arrays.asList(element));
return list;
}
public void genericTest() {
List<String> listStr = getArrayList("element1","element2","element3");
List<Integer> listInt = getArrayList(1,2,3);
}
규칙 : 리턴 타입 앞에 '타입 파라미터'를 명시 <K>
getArrayList() 함수의 리턴타입은 'List<K>' 이고 파라미터 타입은 'K' 이다
*이 처럼 타입을(<T>) 파라미터나 리턴에 사용하는 메소드를 '제네릭 메소드' 라고 한다
#예제 4 - 타입을 제한하고 싶을 때
타입을 외부에서 정하고 자유롭게 사용할 수 있는게 Generic이지만 필요한경우 타입을 제한 할 수 있다
<T extends 최상위타입> 형태로 사용한다.
Number 타입으로 제한된 Prameter만 전달 받아서, 더하기 후 Double 형태로 반환 하는 예제
"1","2" String은 Number 타입이 아니므로 사용할 수 없는 것을 볼 수 있다.
public <T extends Number> Double add(T param1, T param2) {
double value1 = param1.doubleValue();
double value2 = param2.doubleValue();
return value1 + value2;
}
public void test() {
// Double result = add("1","2");//String은 Number 타입이 아니므로, 컴파일 에러
Double result01 = add(1,2);
Double result02 = add(1.0,2.0);
}
#예제 5 - Generic 상속
Generic을 사용하는 클래스/인터페이스도 부모 클래스가 될 수 있고, 상속이 가능하다
Student<T> 클래스를 부모로 하는 HighSchoolStudent<T,C> 클래스로 확인해 보자
public class Student<T> {
private T id;
public T getId() {
return id;
}
public void setId(T id) {
this.id = id;
}
}
public class HighSchoolStudent<T, C> extends Student<T> {
private C name;
public C getName() {
return name;
}
public void setName(C name) {
this.name = name;
}
}
public void test() {
HighSchoolStudent<Integer, String> highSchoolStudent = new HighSchoolStudent();
highSchoolStudent.setId(1);
highSchoolStudent.setName("Tina");
}
문제 있을시 알려 주세요.
좋은 하루 되세요!
'Java' 카테고리의 다른 글
[JAVA] 추상클래스/인터페이스 (+Kotlin) (1) | 2021.12.16 |
---|