Replies: 3 comments
-
아이템 제목 에서 effective java를 통한 학습 내용이 스프링을 이해하는데 있어서 중요한 지식이라는 것도 알게 되었구요. 정리 감사합니다. |
Beta Was this translation helpful? Give feedback.
-
타입 안전 이종 컨테이너... 😤 (한국어로 번역된 책을 다시 한국어로 번역해야하는 책이 있다
저도 스프링 개념 다시 정리 들어갈 때 감사합니다. |
Beta Was this translation helpful? Give feedback.
-
진짜 어려운 파트 맡으셔서 고생 많으셨습니다! |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
0. 들어가며
33번은
타입 안전 이종 컨테이너
에 대한 이야기를 하는 아이템입니다.이 단어를 하나 하나 분해하여 의미를 파악해보겠습니다.
이를 합쳐서 생각해보면 다음과 같습니다.
의미를 알았으니 더 자세한 내용은 아래에서 알아보겠습니다.
1. 타입 안전 이종 컨테이너(비한정적 타입 토큰)
먼저 책에서 타입 이종 컨테이너를 설명하기위해 제시한 코드를 살펴봤습니다.
이 코드에서 Map 의 Key 로
Class<?>
를 받는데요.이를 책에서는 타입 토큰 이라고 표현하고, 더 정확히는 '비한정적 타입 토큰'이라고 부를 수 있습니다.
저는 이 코드를 보고 가장 먼저 일급 컬렉션이 떠올랐습니다.
Favorites 클래스는 Map 을 감싼 일급 컬렉션이고, 타입(타입 토큰)이 key 가 되고 해당 인스턴스가 value 로 되어있는 형태입니다.
그런데 이 예제 코드를 보고 뭔가 익숙한 하나가 더 떠올랐는데요.
제가 익숙함을 느낀 그 대상은 스프링에서의 빈 컨테이너입니다.
1.1 스프링 빈 컨테이너
보통 스프링 빈을 자동 주입받아서 사용하지만, 아래의 예시처럼 가끔 ApplicationContext 를 통해 직접 가져오기도 합니다.
context.getBean
을 호출하면 대략 다음과 같은 클래스들을 타고 이동하며 bean 을 가져옵니다.(설명을 위해 아주 많은 부분을 생략하고 간소화한 그림이니 참고 부탁드립니다.)
여기서 A, B를 합치면 책에서 소개한 타입 이종 컨테이너 Favorites 예제와 같은 구조가 됩니다.
하지만 스프링에서 이렇게 두 단계로 한 이유중 하나는 bean 이름을 붙이는 기능을 지원하기 위함입니다.
1.2 Collectinos
이외에도 이를 활용한 사례들을 책에서 소개해주었습니다.
java.utils.Collections 의 checkedSet, checkedList, checkedMap 과 같은 메서드들을 인데요.
소스를 까보니 그냥 모든 작업에 typeCheck 작업이 들어가있는 구현체를 반환하는 메서드였습니다.
그래서 제네릭만 제대로 써도 필요없는것 아닌가 했는데, 조금 더 읽어보니 로 타입을 위한 기능이라고 합니다.
로 타입은 제네릭이 자바에 정착하기전에 생겼던 안티패턴이지만 하위호환성을 위해 지원하는 문법이라고 합니다.
(자세한 내용은 아이템 26. 로 타입은 사용하지 말라 참고)
2. 슈퍼 타입 토큰
그런데 앞에서 살펴본 형태의 타입 안전 이종 컨테이너는 제네릭 타입은 담지 못한다는 단점이 있습니다.
위 처럼 가령
List<String>
혹은Set<Integer>
타입을 key 로 할 수 없습니다.이를 해결할 수 있는 방법으로 슈퍼 타입 토큰이라는 개념을 소개했는데요.
이 내용은 설명이 너무 길어질 수 있어 슈퍼타입토큰(Super Type Token) 글을 참고하시는걸 강추드립니다.
(추가로 책에서는 닐 개프터의 글도 추천합니다.)
3. 한정적 타입 토큰
1번에서 살펴봤던 예제에서는 제네릭에 와일드카드만 사용되었는데요.
와일드카드 대신 한정적 타입을 선언하는 방법도 있습니다.
이 메서드는 객체에 해당 타입의 어노테이션이 달려있다면 그 어노테이션을 반환하고, 아니라면 null 을 반환합니다.
즉, 이는 타입 안전 이종 컨테이너인 것이죠.
3.1 Class 클래스의 asSubClass 메서드
만약 Class<?> 객체를 3번에서처럼 한정적 타입만 받는 메서드에 넘기려면 어떻게 해야할까요.
이런 형태도 가능하긴 하지만 비검사 형변환이기 때문에 컴파일시 경고가 발생합니다.
이렇게 한다면 컴파일 경고 없이 넘길 수 있습니다.
Beta Was this translation helpful? Give feedback.
All reactions