본문 바로가기
개발/JAVA

[effective java 3/E] 제네릭 <로 타입은 사용하지 말라>

by 상용최 2020. 7. 11.
반응형

제네릭을 사용할 때 로 타입(raw type)은 절대 사용하면 안된다.

왜 사용하면 안되는지 알아보기 전에 로 타입이 무엇인지 모르시는분들을 위해 용어 설명을 먼저 하겠다.

 

클래스와 인터페이스 선언에 타입 매개변수가 쓰이면 제네릭 클래스 or 제네릭 인터페이스라고 한다.

제네릭 클래스와 제네릭 인터페이스를 통틀어 제네릭 타입이라고 한다.

각각의 제네릭 타입은 매개변수화 타입을 정의한다. ex) List<String>

제네릭 타입을 하나 정의하면 그에 딸린 로 타입(raw type)도 함께 정의된다.

예를든다면 List<E>를 정의하면 List가 함께 정의되는데 List가 List<E>의 로 타입이다.

 

로 타입이 무엇인지 알아보았으니 이제 왜 사용하면 안되는지를 알아 보겠다.

 

오류는 가능한 한 컴파일 시점에 발견해야 한다.

"로 타입 얘기를 하다가 뜬금없이 이 얘기는 왜 하는거지?" 라고 생각할 수 있다.

오류는 컴파일 시점에 잡는것이 가장 좋다.

서비스를 운영하다가 발생하는 오류(런타임 오류)는 원인을 찾기가 굉장히 힘들며 운영하는 서비스의 평판을 안 좋게한다.

로 타입을 사용하게 되면 런 타임시점에 오류를 발생시킬 확률이 굉장히 높다.

간단하지만 로 타입을 사용하게 된다면 발생할 수 있는 예시를 들어보도록 하겠다.

public final class main {
    public static void main(String[] args) {
        List list = new ArrayList<>();
        list.add("123123");
        Integer integer = (Integer) list.get(0); // 런타임 에러
    }
}

1번째 라인에서 로타입으로 선언하고 2번째 라인에서 123123을 String 타입으로 추가하였다.

여기까지는 문제가 없다. 

문제는 3번째 라인에서 발생한다.

리스트에서 Item을 꺼내와서 Integer 타입으로 변환하려고 했다.

하지만 ClassCastException이 발생한다.

 

물론 String 타입으로 가져온다면 아무 문제도 발생하지 않는다.

하지만 실무에서는 혼자만 개발하는게 아니라 여러명이서 개발한다.

그 중 한명이라도 타입이 명시되어 있지 않은 로 타입을 다룰 때 100% 실수를 안한다는 보장이 있나?

로 타입을 사용한다는것은 오류를 발생시킬 여지를 남겨두겠다는것과 똑같다고 생각한다.

 

위에 예제에서 볼 수 있듯 로 타입을 사용하면 제네릭이 주는 안정성과 표현력을 모두 잃게된다.

 

 

그러면 로 타입을 왜 만들었어 ?

그렇다면 로 타입을 왜 만들었을까?

JAVA에서는 제네릭이 나오기 이전에도 많은 코드가 만들어졌다.

그런 상황에서 로타입이 없다면 기존에 만들어진 코드들은 오류덩어리가 될것이다.

그런 상황을 방지하기 위해 (하위호환성을 위해) 로타입을 만들었다.

 

 

반응형

댓글