제네릭스(Generics)
제네릭스는 '매개변수화된 자료형'이다.
제네릭스는 클래스, 인터페이스 또는 메소드에 적용될 수 있다.
제네릭 메소드에 대해서 얘기해본다. 메소드에 인수를 넘길 때는 반드시 해당하는 매개변수의 자료형과 일치되는 자료형을 갖는 인수를 넘겨야 한다. 즉, 정수 매개변수에는 정수 인수를넣어야 한다.
void sort(Integer[] x){
}
void sort(Double[] x){
}
위의 두 sort 메소드는 정렬하려는 자료형만 다를 뿐 메소드의 내용이 같다.
이런 경우 자료형 자체를 매개변수와 같이 만들 수가 있다.
void sort(T[] x){
}
T는 어떤 객체도 올 수 있다는 의미이다.
void set( Integer x ) { } |
매개변수 x 에는 Integer 객체를 넣을 수 있다. |
void set( T x ) { } |
매개변수 T 자리에는 자료형이 와야한다. 이것은 어떤 자료형도 T에 넣을 수 있다는 표현이다. |
정렬 프로그램과 같이 많은 프로그램들이 자료형에 관계없이 같은 코드를 사용해야 하는 경우가 있다. 이러한 경우 제네릭스가 아주 유용하다.
즉, 제네릭스는 코드 재사용성을 높여준다. 사용시에 주의 할 점이 있다면, 레퍼런스형(참조형 클래스)만 제네릭스로 사용할 수 있다. (int, double 등과 같은 기본 자료형은 제네릭스로 사용할 수가 없다.)
제네릭 클래스
제네릭 클래스는 일반적으로 아래 왼쪽의 형태를 갖는다. 그리고 이 클래스의 객체를 생성할 때에는 <>기호를 사용하여 어떤 타입의 인수를 넣을지 알려야한다.
클래스명<매개변수 타입 리스트> { ... } |
클래스명<타입> 객체명 = new 클래스명<타입>( ); |
<제네릭 클래스와 제네릭 메소드 예제>
class Data<T> { // 클래스명 옆에 제네릭 기호<>를 적고 그 안에 매개변수 기술
T obj; // 인스턴스 변수 obj의 자료형은 T
Data(T ob) { // 생성자 Data는 자료형이 T인 인수 한 개를 입력받는다.
obj = ob;
}
T getObj() { // 인스턴스 변수 ojb의 자료형은 T임.
return obj;
}
void showType() {
System.out.println("Type of T : " + obj.getClass().getName());
}
}
public class Code229 {
public static void main(String[] args) {
Data<Integer> d1 = new Data<Integer>(100); // 정수 100 인수
System.out.println(d1.getObj());
d1.showType();
Data<String> d2 = new Data<String>("JAVA"); //문자열 "JAVA" 인수
System.out.println(d2.getObj());
d2.showType();
}
}
<출력결과>
100
Type of T : java.lang.Integer
JAVA
Type of T : java.lang.String
위의 Data 클래스는 제네릭 클래스이고, getObj메소드는 제네릭 메소드라고 한다.
제네릭에 이용할 수 있는 자료형
제네릭으로 사용할 수 있느 자료형은 레퍼런스 형이어야 한다. int, double 등과 같은 자바의 기본 자료형은 제네릭으로 사용할 수 없다. 만약 기본자료형을 제네릭으로 사용하고자 한다면, 위의 예처럼 wrapper 클래스인 Integer, Double 등을 이용해야 한다.
제네릭 타입도 엄격하게 문법에 따라야 한다.
제네릭타입이 다른것들 끼리 비교하려고 한다면 에러가 발생한다.
제한된 제네릭 타입
제네릭을 제한된 형태로 사용해야 하는 경우가 있다.
<T extends V>
위와 같이 적혀 있다면 제네릭 T자리에는 클래스 타입이 V이거나 V 클래스의 하위 클래스 타입만 올 수 있다는 뜻이다.
class Data0<T extends Number> { //Number 클래스의 하위 클래스 타입
T obj;
Data0(T ob) {
obj = ob;
}
int calcMultiple(int n){
return obj.intValue()*n;
}
}
public class Code231 {
public static void main(String[] args) {
Data0<Integer> d = new Data0<Integer>(100); //Integer는 Number의 하위 클래스
int result = d.calcMultiple(5);
System.out.println(result);
Data0<Double> e = new Data0<Double>(17.5); //Double 역시 Number의 하위 클래스
int result2 = e.calcMultiple(5);
System.out.println(result2);
}
}
<출력결과>
500
85
와일드카드 인수
와일드카드는 "?"로 나타낸다. 와일드카드 자리에는 어떤 클래스 타입도 올 수 있다는 의미이다.
class WithWild<T extends Number>{
T data;
WithWild(T d){ data = d; }
boolean same(WithWild<?> x){
if(Math.abs(data.doubleValue()) == Math.abs(x.data.doubleValue()))
return true;
return false;
}
}
public class Code232 {
public static void main(String[] args) {
WithWild<Integer> a = new WithWild<Integer>(6);
WithWild<Double> b = new WithWild<Double>(-6.0);
WithWild<Long> c = new WithWild<Long>(5L);
if (a.same(b)) System.out.println("a and b are equal");
else System.out.println("a and b are different");
if (a.same(c)) System.out.println("a and c are equal");
else System.out.println("a and c are different");
}
}
출력결과
a and b are equal
a and c are different
'JAVA > 개념' 카테고리의 다른 글
자바(JAVA) int형 Integer형 (0) | 2022.01.26 |
---|---|
자바(JAVA) - 클래스, 객체, 인스턴스의 개념 (0) | 2022.01.14 |
자바(JAVA) - 예외 처리(Exception Handling) (0) | 2022.01.06 |
자바(JAVA): 인터페이스(interface) (0) | 2022.01.05 |
자바(JAVA) : 패키지(package), 임포트(Import), 클래스패스(ClassPath) (0) | 2022.01.05 |