본문 바로가기
Java의 정석/제네릭스, 열거형, 어노테이션

제네릭스 (Generics)

by Hwanii_ 2023. 10. 11.
728x90

제네릭스 (Generics) 란 ?

 

1.

컴파일을 할 때, 타입을 체크해주는 기능 (compile-time type check) - JDK 1.5

 

예시 )

 

//	Tv 객체만 저장할 수 있는 배열리스트 생성

ArrayList<Tv> tvList = new ArrayList<Tv>();

tvList.add(new Tv());	//	OK
tvList.add(new Audio());	//	컴파일 에러. Tv 타입 외에 다른 타입 데이터 저장 불가

 

//	예시

package ch12;

import java.util.ArrayList;

public class GenericTest {

    public static void main(String[] args) {

        ArrayList list = new ArrayList();

        list.add(10);
        list.add(20);
        list.add("30"); //  String 타입의 데이터 추가

        Integer i = (Integer) list.get(2);  //  컴파일 OK

        System.out.println(list);   //  형 변환 에러 발생
    }

}   //  GenericTest

 

위와 같이 코드를 작성하고 배열리스트에 2번째 요소 데이터를 Integer 타입으로 형변환 하는 코드를 작성 하면

컴파일러는 해당 코드에 문제가 있다는 것을 알 수 없다.

>> 컴파일러의 한계

 

그래서 list  참조변수를 출력 하면 ClassCastException 예외가 발생 하게 된다.

 

그래서 실행시 예외가 발생하는것 보다

컴파일 에러가 발생 해서 프로그램을 동작 시키기 전에 예외를 잡아 내기 위한 방법으로 제네릭을 사용 하게 됌

 

< >  을 사용해서 타입을 명시해주면 된다.

 

 

빨간 밑줄이 뜨면서 컴파일 에러가 발생 한다.

 

만약에 모든 타입의 데이터를 배열리스트에 저장 하고 싶으면 <Object> 로 명시해주면 된다.

 

 

 

[ 참고 ]

 

JDK 1.5 이전에는 일반 클래스 들에 <E> 가 붙어 있지 않았는데,

JDK 1.5 이후에 제네릭 개념이 도입 되면서,

클래스 내부에 Object 타입이 있는 클래스 들은 <E> 가 붙게 되었다.

 

 

이미지와 같이 클래스 옆에 <E> 와 같이 타입이 붙어 있는 클래스를 "제네릭 클래스" 라고 한다.

따라서 제네릭 클래스를 사용 할 때는 타입을 작성해주면 된다.

 

 

 

2.

객체의 타입 안정성을 높이고 형변환의 번거로움을 줄여 준다.

 

 

배열리스트에 들어있는 데이터 타입이 Tv 타입 밖에 없기 때문에 데이터를 꺼낼 때 형변환을 해주지 않아도 된다.

>> 컴파일러가 자동으로 형변환을 해준다.

 

 

 

[ 정리 ]

 

제네릭스의 장점

 

1. 타입 안정성을 제공.

>> ClassCastException 예외 발생이 사라진다.

 

2. 타입체크와 형변환을 생략할 수 있으므로 코드가 간결해진다. 

 

 

 

[ 참고 ]

 

예외의 상속 계층도

 

 

ClassCastException 예외는 개발자의 실수로 인해 발생하는 RuntimeException의 자손 클래스 이다.

 

RuntimeException 은 실행을 하고 나서 발생 되는 예외 이다.

실행을 하고 나서 예외가 발생 되는것 보다,

제네릭을 명시해줌으로써, 컴파일 타임에 에러가 발생 하도록 하기 위함 이다.

 

"런타임 에러를 어떻게 하면 컴파일 타임으로 가져올 수 있을까 ?" 를 고민하다가 나온 개념

>> 제네릭

 

위와 같이 예외가 최대한 발생 하지 않도록 노력 하는것은 NPE 에서도 예시를 들 수 있다.

 

예를들어서 Object[] 타입의 배열을 선언 할 때,

 

Object[] objArr = null;

 

이렇게 null 로 초기화를 하게 되면, objArr 참조변수로 무언가 메서드를 사용 할때, NPE 가 발생 하게 된다.

 

그래서 NPE 를 방지 하기 위해서 코드 작성을 아래와 같이 할 수 있다.

 

Object[] objArr = new Object[0];	//	길이가 0인 배열 생성

또는

Object[] objArr = {};	//	길이가 0인 배열 생성
반응형