본문 바로가기

Java 공부

13장 제네릭(Generic) (3)_제네릭 메소드

제네릭은 타입을 선언할 때 뿐만 아니라 메소드를 선언할 때에도 제네릭을 사용할 수 있다.


제네릭 메소드?

- 매개변수 타입과 리턴 타입으로 타입 파라미터를 갖는 메소드를 말한다.

- 제네릭 메소드 선언 방법

- 리턴타입 앞에 < > 기호를 추가하고 타입 파라미터를 기술한다.

- 타입 파라미터를 리턴타입과 매개변수에 사용한다.

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으로 대체되어 들어간다.





본 포스팅은 이것은 자바다 책을 참고하여 작성하였습니다.