Effective Java 3E
학습기록 - 이왕이면 제네릭 메서드로 만들라
클래스와 마찬가지로, 메서드도 제네릭으로 만들 수 있다. 매개변수화 타입을 받는 정적 유틸리티 메서드는 보통 제네릭이다. 예컨대 Collection의 '알고리즘' 메서드(binarySearch, sort 등)는 모두 제네릭이다. 제네릭 메서드 작성법은 제네릭 타입 작성법과 비슷하다. 다음은 두 집합의 합집합을 반환하는 문제가 있는 메서드다. 1 2 3 4 5 public static Set union(Set s1, Set s2){ Set result = new HashSet(s1); result.addAll(s2); return result; } Colored by Color Scripter cs 컴파일은 되지만 경고가 두 개 발생한다. 경고를 없애려면 이 메서드를 타입 안전하게 만들어야 한다. 메서드 ..
학습기록 - 이왕이면 제네릭 타입으로 만들라
JDK가 제공하는 제네릭 타입과 메서드를 사용하는 일은 일반적으로 쉬운 편이지만, 제네릭 타입을 새로 만드는 일은 조금 더 어렵다. 그래도 배워두면 그만한 값어치는 충분히 한다. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 public class Stack{ private Object[] elements; private int size = 0; private static final int DEFAULT_INITIAL_CAPACITY = 16; public Stack(){ elements = new Object[DEFAULT_INITIAL_CAPACITY]; } public void push(Objec..
학습기록 - 배열보다는 리스트를 사용하라
배열과 제네릭 타입에는 중요한 차이가 두 가지 있다. 첫 번째, 배열은 공변(convariant)이다. 어려워 보이는 단어지만 뜻은 간단하다. Sub가 Super의 하위 타입이라면 배열 Sub[]는 배열 Super[]의 하위 타입이 된다(공변 즉, 함께 변한다는 뜻이다). 반면, 제네릭은 불공변(invariant)이다. 즉, 서로 다른 타입 Type1과 Type2가 있을 때, List은 List의 하위 타입도 아니고 상위 타입도 아니다. 이것만 보면 제네릭에 문제가 있다고 생각할 수도 있지만, 사실 문제가 있는 건 배열쪽이다. 다음은 문법상 허용되는 코드다. 1 2 Object[] objectArray = new Long[1]; objectArray[0] = "타입이 달라 넣을 수 없다."; cs 하지만..
학습기록 - 비검사 경고를 제거하라
제네릭을 사용하기 시작하면 수많은 컴파일러 경고를 보게 될 것이다. 비검사 형변환 경고, 비검사 메서드 호출 경고, 비검사 매개변수화 가변인수 타입 경고, 비검사 변환 경고 등이다. 제네릭에 익숙해질수록 마주치는 경고 수는 줄겠지만 새로 작성한 코드가 한 번에 깨끗하게 컴파일되리라 기대하지는 말자. 대부분의 비검사 경고는 쉽게 제거할 수 있다. 코드를 다음처럼 잘못 작성했다고 해보자. 1 Set exaltation = new HashSet(); cs 그러면 컴파일러는 무엇이 잘못됐는지 친절히 설명해 줄 것이다. 컴파일러가 알려준 대로 수정하면 경고가 사라진다. 사실 컴파일러가 알려준 타입 매개변수를 명시하지 않고, 자바 7부터 지원하는 다이아몬드 연산자()만으로 해결할 수 있다. 그러면 컴파일러가 올바른..
학습기록 - 로 타입은 사용하지 말라
용어부터 정리하고 가자. 클래스와 인터페이스 선언에 타입 매개변수(type parameter)가 쓰이면, 이를 제네릭 클래스 혹은 제네릭 인터페이스라 한다. 예컨대 List 인터페이스는 원소의 타입을 나타내는 타입 매개변수 E를 받는다. 그래서 이 인터페이스의 완전한 이름은 List지만, 짧게 그냥 List라고도 자주 쓴다. 제네릭 클래스와 제네릭 인터페이스를 통틀어 제네릭 타입(Generic type)이라 한다. 각각의 제네릭 타입은 일련의 매개변수화 타입(parameterized type)을 정의한다. 먼저 클래스(혹은 인터페이스) 이름이 나오고, 이어서 꺽쇠괄호 안에 실제 타입 매개변수들을 나열한다. 예컨대 List은 원소의 타입이 String인 리스트를 뜻하는 매개변수화 타입이다. 여기서 Stri..
학습기록 - 톱레벨 클래스는 한 파일에 하나만 담으라
소스 파일 하나에 톱레벨 클래스를 여러 개 선언하더라도 자바 컴파일러는 불평하지 않는다. 하지만 아무런 득이 없을뿐더러 위험을 감수해야 하는 행위다. 이렇게 하면 한 클래스를 여러 가지로 정의할 수 있으며, 그중 어느 것을 사용할지는 어느 소스 파일을 먼저 컴파일하냐에 따라 달라지기 때문이다. 구체적인 예를 보자. 다음 소스 파일은 Main 클래스 하나를 담고 있고, Main 클래스는 다른 톱레벨 클래스 2개(Utensil과 Desset)를 참조한다. 1 2 3 4 5 public class Main{ public static void main(String[] args){ System.out.println(Utensil.NAME + Dessert.NAME); } } Colored by Color Scri..