제네릭은 타입을 선언할 때 뿐만 아니라 메소드를 선언할 때에도 제네릭을 사용할 수 있다.
제네릭 메소드?
- 매개변수 타입과 리턴 타입으로 타입 파라미터를 갖는 메소드를 말한다.
- 제네릭 메소드 선언 방법
- 리턴타입 앞에 < > 기호를 추가하고 타입 파라미터를 기술한다.
- 타입 파라미터를 리턴타입과 매개변수에 사용한다.
public<타입파라미터,..> 리턴타입 메소드명(매개변수,...) { ... }
public <T> Box<T> boxing(T t) { .... }
예제1 >>
제네릭 타입으로 선언된 Box클래스
public class Box<T> {
private T t;
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
}
제네릭 메소드를 가지는 Util 클래스
public class Util {
public static <T> Box<T> boxing(T t){
Box<T> box = new Box<T>();
box.setT(t);
return box;
}
}
Util 클래스는 static타입의 제네릭 메소드를 가진다.
public static <T> Box<T> boxing(T t)
<T> : 타입파라미터
Box<T> : 리턴타입
boxing(T t) : 메소드명(매개변수)
실행클래스
public class BoxingMethodExample {
public static void main(String[] args) {
// 1) 타입 지정
Box<Integer> box1 = Util.<Integer>boxing(100);
int intValue = box1.getT();
System.out.println(intValue);
// 2)타입 지정 생략
Box<String> box2 = Util.boxing("홍길동");
String strValue = box2.getT();
System.out.println(strValue);
}
}
결과값
100
홍길동
boxing메소드는 static메소드 --> 객체 생성 없이 바로 사용
1) 타입 지정
boxing메소드는 제네릭 메소드이기 때문에 <>안에 구체적인 타입이 지정해 주어야 한다. 따라서 <Integer>boxing으로 사용
2)타입 지정 생략
<>안에 구체적인 타입을 지정해주지 않아도 컴파일러는 "홍길동"을 보고 타입을 유추하여 T 자리에 String으로 변환한다.
이처럼 제네릭 메소드를 사용할 때에는 타입지정을 명시적으로 해도 되고, 생략해주어도 된다.
예제2 >>
제네릭 메소드를 가지는 Util 클래스
2개의 Pair객체를 받아서 비교하여 K,V중 하나라도 다른것이 있으면 false를 리턴하는 함수 Compare를 만든다.
public class Util {
//타입파라미터 리턴타입 메소드명 (매개변수)
public static <K,V> boolean compare(Pair<K,V> p1, Pair<K,V> p2) {
boolean KeyCompare = p1.getKey().equals(p2.getKey());
boolean valueCompare = p1.getValue().equals(p2.getValue());
return KeyCompare && valueCompare;
}
}
compare메소드는 매개변수로 재네릭 타입인 Pair객체를 받기 때문에 메소드 앞머리에 K,V에 대한 타입정의가 필요하다.
&& => 논리연산 둘중에 하나가 false가 되면 false리턴
제네릭 타입으로 선언된 Pair클래스
public class Pair<K,V> {
private K key; //키
private V value; //value
public Pair(K key, V value) {
this.key = key;
this.value = value;
}
public K getKey() {
return key;
}
public void setKey(K key) {
this.key = key;
}
public V getValue() {
return value;
}
public void setValue(V value) {
this.value = value;
}
}
실행클래스
public class CompareMethodExample {
public static void main(String[] args) {
// 1)생략 안한 경우
Pair<Integer,String> p1 = new Pair<>(1,"사과");
Pair<Integer,String> p2 = new Pair<>(1,"사과");
boolean result1 = Util.<Integer,String>compare(p1, p2);
if(result1) {
System.out.println("논리적으로 동등한 객체입니다.");
}else {
System.out.println("논리적으로 동등하지 않은 객체입니다.");
}
// 2)생략 한 경우
Pair<String,String> p3 = new Pair<>("user1","홍길동");
Pair<String,String> p4 = new Pair<>("user2","홍길동");
boolean result2 = Util.compare(p3, p4);
if(result2) {
System.out.println("논리적으로 동등한 객체입니다.");
}else {
System.out.println("논리적으로 동등하지 않은 객체입니다.");
}
}
}
결과값
논리적으로 동등한 객체입니다.
논리적으로 동등하지 않은 객체입니다.
1) 생략 안한 경우
Util 클래스의 Compare메소드를 사용 시, 앞머리에 <>로 타입 정의를 해준다.
2) 생략 한 경우
Util 클래스의 Compare메소드를 사용 시, 타입정의 생략 컴파일러는 p3,p4타입을 유추하여 K,V자리에 변환한다.
해당예제에서 p3,p4의 K,V가 String,String이므로 String으로 대체되어 들어간다.
본 포스팅은 이것은 자바다 책을 참고하여 작성하였습니다.
'Java 공부' 카테고리의 다른 글
13장 제네릭(Generic)(5)_와일드 카드 타입 (0) | 2019.05.24 |
---|---|
13장 제네릭(Generic)(4)_제한된 타입 파라미터 (0) | 2019.05.23 |
13장 제네릭(Generic) (2)_멀티 타입 파라미터 (0) | 2019.05.22 |
13장 제네릭(Generic) (0) | 2019.01.20 |
12장 스레드풀(4) (0) | 2018.12.12 |