제네릭스 문제로 이해하기
문제
int와 String 어레이를 아규먼트로 받아서 출력하는 single 메서드를 작성하시오.
제네릭스를 사용하지 않고 문제 풀기
캐스팅을 이용한 코드
import java.io.IOException; import java.lang.reflect.Method; class Printer { void printArray(Object[] arr) { try { for(Object i : arr) { System.out.println((String)i); } return; } catch (Exception e) { for(Object i : arr) { System.out.println((Integer)i); } } } } public class Solution { public static void main( String args[] ) { Printer myPrinter = new Printer(); Integer[] intArray = { 1, 2, 3 }; String[] stringArray = {"Hello", "World"}; myPrinter.printArray(intArray); myPrinter.printArray(stringArray); } }
Object
타입 어레이로 받아서 캐스팅하여 출력했다. 여기서는try-catch
문을 사용하여서 캐스팅하였다. 만약 int 어레이가 들어온다면 try문 안에서 String으로 캐스팅하려 하는 과정에서java.lang.ClassCastException
이 발생하여 catch문 안의 구문이 실행될 것이다.
타입체크를 이용한 코드
import java.io.IOException; import java.lang.reflect.Method; class Printer { void printArray(Object[] arr) { if(arr[0].getClass().getName() == "java.lang.String") { for(Object i : arr) { System.out.println((String)i); } return; } else { for(Object i : arr) { System.out.println((Integer)i); } } } } public class Solution { public static void main( String args[] ) { Printer myPrinter = new Printer(); Integer[] intArray = { 1, 2, 3 }; String[] stringArray = {"Hello", "World"}; myPrinter.printArray(intArray); myPrinter.printArray(stringArray); } }
제네릭스를 이용해서 풀기
제네릭 배열 타입
import java.io.IOException; import java.lang.reflect.Method; class Printer { <T> void printArray(T[] arr) { for(T el : arr) { System.out.println(el); } } } public class Solution { public static void main( String args[] ) { Printer myPrinter = new Printer(); Integer[] intArray = { 1, 2, 3 }; String[] stringArray = {"Hello", "World"}; myPrinter.printArray(intArray); myPrinter.printArray(stringArray); } }
사실 답을 보기 전까지는 못풀었다. 왜냐하면 아규먼트가 ArrayList가 아닌 배열이었기 때문이다. 제네릭 배열은 생성할 수 없다. 그런데 제네릭 배열은 생성할 수 없다는 것은 알았지만, 제네릭 배열 타입의 참조변수를 선언하는 것은 가능하다는 점을 생각하지 못했다.
제네릭 메서드를 사용해서 제네릭 배열 타입 참조변수를 패러미터로 넣어서 풀면 된다.
이 문제는 제네릭스가 왜 필요한지를 잘 보여주는 것 같다. 제네릭스를 사용하지 않았을 때에는 캐스팅을 하거나, 타입체크를 했어야 했다. 하지만 제네릭스는 컴파일 시 타입체크를 해주기 때문에, 타입체크와 캐스팅을 직접 할 필요가 없다.