본문 바로가기

언어공부/Java

자바 제네릭(지네릭스, Generics), 와일드카드

자바 제네릭(지네릭스, Generics)에 대해서 알아보자

제네릭(지네릭스, Generics)

지네릭스는 다양한 타입의 객체들을 다루는 메소드나 컬렉션 클래스에 컴파일 시의 타입 체크(compile-time type check)를 해주는 기능이다. 객체의 타입을 컴파일 시에 체크하기 때문에 객체의 타입 안정성을 높이고 형변환의 번거로움이 줄어든다.

 

지네릭스가 나온 배경으로 컬렉션은 복수개의 타입을 동시 저장하다 보니 원하는 추출이 어렵다. 그러므로 지정한 타입만 저장하기 위해서 나온것이 지네릭스다.

 

지네릭스를 지정하면 원하는 자료형 추출이 쉽다. 불필요한 타입 변환을 할 필요가 없기 때문에 프로그램 성능이 향상된다. 컴파일 시 강한 타입 체크를 할 수 있기 때문에 자료의 안정성이 보장된다.

 

예를 들어 ArrayList의 경우 다양한 종류의 객체를 담을 수 있긴 하지만 보통 한 종류의 객체를 담는 경우가 많다. 아래와 같이 ArrayList를 생성할 때, 저장할 객체의 타입을 지정해주면, 지정한 타입 외에 다른 타입의 객체가 저장되면 에러가 발생한다.

ex) ArrayList<TV> tvList = new ArrayList<TV>(); //TV객체만 저장할 수 있는 ArrayList를 생성

tvList.add(new TV()); //OK

tvList.add(new Audio());//컴파일 에러. TV외에 다른 타입은 저장 불가

** JDK 1.7부터 ArrayList<TV> tvList = new ArrayList<>(); 로 뒷부분에 TV를 생략할 수 있다. 

 

그리고 저장된 객체를 꺼낼 때는 형변환하랄 필요가 없어서 편리하다. 이미 어떤 타입의 객체들이 저장되어 있는지 알고 있기 때문이다. 

 

ex)

 

toUpperCase()메소드를 사용하려면 String클래스여야 한다. 지네릭스를 사용하지 않으면 다운캐스팅을 해야 하지만, 지네릭스를 사용하면 이미 String타입의 객체가 저장된 것을 알기 때문에 다운캐스팅을 하지 않아도 된다.

 

출력화면

 


와일드카드

지네릭 클래스를 생성할 때, 참조변수에 지정된 지네릭 타입과 생성자에 지정된 지네릭 타입은 일치해야 한다. (서로 상속관계여도 동일) 지네릭 타입에 다형성을 적용하기 위해서 지네릭타입으로 와일드카드를 사용하면 된다.

 

  • <? extends T> : 와일드 카드의 상한 제한. T와 그 자손들만 가능
  • <? super T> : 와일드 카드의 하한 제한. T와 그 조상들만 가능
  • <?> : 제한 없음. 모든 타입이 가능. <? extends Object>와 동일.

와일드 카드를 이용하면 예제와 같이 하나의 참조변수로 다른 지네릭 타입이 지정된 객체를 다룰 수 있다.

 

ex)

<?extends Object>(==<?>)가 아닌 <Object> 인 상태에서 objList=v;를 하면 에러가 발생한다. Object타입과 String타입이기 때문이다. 

출력화면

 

ex)

 

출력화면.