해결된 질문
작성
·
237
답변 1
1
안녕하세요?
이해를 돕기 위해 강의에서 사용된 Coffee 클래스를 조금 변경하겠습니다. 생성자가 아닌 setName() 메소드를 추가하여 이 메소드가 호출될 때 이름 정보를 설정하도록 하겠습니다.
public class Coffee <T>{
public T name;
public void setName(T name) {
this.name = name;
}
public void ready() {
System.out.println("커피 준비 완료 : " + name);
}
}
이때 제네릭 클래스인 Coffee 는 아래와 같이 객체를 생성할 때 자료형이 결정됩니다. c1 의 경우 자료형을 Integer 로 하였기 때문에 setName() 메소드를 호출할 때 정수만 사용 가능합니다. c2 의 경우 자료형을 String 으로 하였기 때문에 setName() 메소드를 호출할 때 문자열만 사용 가능합니다.
Coffee<Integer> c1 = new Coffee<>(); // 자료형 : 정수
c1.setName(35);
c1.ready();
Coffee<String> c2 = new Coffee<>(); // 자료형 : 문자열
c2.setName("나도코딩");
c2.ready();
반면에 제네릭 메소드는 메소드를 호출할 때 자료형이 결정됩니다. 메소드를 호출하면서 원하는 형태의 값을 전달하게 되는데요.
orderCoffee(35, "아메리카노"); // <정수, 문자열>
orderCoffee("나도코딩", "라떼"); // <문자열, 문자열>
이때, 자바 컴파일러는 전달값으로 입력한 <35, "아메리카노"> 또는 <"나도코딩", "라떼"> 로부터 orderCoffee() 메소드의 T, V 를 각각 Integer, String 등으로 유추할 수 있습니다. 그래서 <Integer>, <String> 을 따로 명시하지 않고 생략 가능합니다.
public static <T, V> void orderCoffee(T name, V coffee) {
System.out.println(coffee + " 준비 완료 : " + name);
}
생략하지 않고 사용하는 형태는 이렇습니다. 설명을 위해 orderCoffee() 메소드를 별도의 클래스로 이동하였습니다.
public class Cafe {
public static <T, V> void orderCoffee(T name, V coffee) {
System.out.println(coffee + " 준비 완료 : " + name);
}
}
그리고 main() 메소드에서 다음과 같이 이 메소드를 호출해보겠습니다.
Cafe.<Integer, String>orderCoffee(35, "아메리카노");
Cafe.<String, String>orderCoffee("나도코딩", "라떼");
이렇게 하면 첫 줄에는 전달값으로 반드시 <정수, 문자열> 형태의 값을 넣어야 하며, 둘째 줄에는 <문자열, 문자열> 형태의 값을 넣어야 합니다. 단, 앞서 말씀드린대로 제네릭 메소드는 전달값으로부터 자료형을 유추할 수 있기 때문에 위 문장은 다음처럼 작성할 수 있습니다. 이때는 전달값으로 입력되는 데이터에 따라 자료형이 결정됩니다.
Cafe.orderCoffee(35, "아메리카노");
Cafe.orderCoffee("나도코딩", "라떼");
이해에 도움되시길 바라겠습니다 😊
감사합니다.