본문 바로가기

책/effective java29

[effective java] item 29. 이왕이면 제네릭 타입으로 만들라 결론 새로운 타입을 설계할 때는 형변환 없이 사용할 수 있는 제네릭 타입으로 만드는 것이 좋습니다. 기존 타입 중 제네릭이었어야 하는 게 있다면 제네릭 타입으로 변경합시다. 기존 클라이언트에는 아무 영향을 주지 않으면서, 새로운 사용자를 훨씬 편하게 해주는 길입니다. 설명 아이템 7에서 다룬 스택 클래스는 원해 제네릭 타입이어야 마땅합니다. 그러니 제네릭으로 만들어봅시다. Object 기반 스택 - 제네릭이 절실한 강력 후보! public class Stack { private Object[] elements; private int size = 0; private static final int DEFAULT_INITIAL_CAPACITY = 16; public Stack() { elements = new.. 2023. 8. 28.
[effective java] item 28. 배열보다는 리스트를 사용하라 결론 배열과 제네릭은 매우 다른 타입 규칙이 적용됩니다. 배열은 공변인 반면, 제네릭은 불공변이고, 배열은 실체화되는 반면, 제네릭은 타입 정보가 소거됩니다. 그 결과 배열은 컴파일 타임에 안전하고 런타임에는 타입 안전하지 않습니다. 제네릭은 반대입니다. 그래서 둘을 섞어 쓰기란 쉽지 않으므로 만약 둘을 섞어 쓰다가 컴파일 오류나 경고를 만나면, 가장 먼저 배열을 리스트로 대체하는 방법을 적용해봅시다. 설명 배열과 제네릭의 차이점 배열과 제네릭에는 다음 두 가지 주요한 차이가 있습니다. 1. 공변(convariant) 배열 제네릭 배열은 공변입니다. 제네릭은 불공변입니다. Sub가 Super의 하위 타입이라면, 배열 Sub[]도 배열 Super[]의 하위 타입입니다. (공변, 즉 함께 변한다는 뜻입니다... 2023. 8. 28.
[effective java] item 27. 비검사 경고를 제거하라 결론 제네릭을 사용할 때, 가능한 한 모든 비검사 경고를 제거해야 합니다. 모든 비검사 경고는 런타임에 ClassCastException을 일으킬 수 있는 잠재적 가능성을 뜻하기 때문입니다. 경고를 없앨 방법을 찾지 못했다면, 그 코드가 타입 안전함을 증명하고 가능한 한 범위를 좁혀 @SuppressWarning("unchecked") 애너테이션으로 경고를 숨깁시다. 그러고 경고를 숨기기로 한 근거를 주석으로 남깁시다. 설명 할 수 있는 한 모든 비검사 경고를 제거해라 제네릭을 사용하기 시작하면 수많은 컴파일러 경고를 보게 될 것입니다. 할 수 있는 한 모든 비검사 경고를 제거해야 합니다. 모두 제거한다면, 그 코드는 타입 안전성이 보장됩니다. 즉, 런타임에 ClassCastException이 발생할 일.. 2023. 8. 28.
[effective java] item 26. 로 타입은 사용하지 말라 결론 로 타입은 런타임 에러를 발생시키므로 사용하면 안 됩니다. 매개변수화 타입인 Set나 비한정적 와일드 카드 타입인 Set은 컴파일 에러를 발생시켜 더 안전하므로, 로 타입인 Set 대신 사용하는 것이 좋습니다. 설명 용어 정리 제네릭 클래스 / 제네릭 인터페이스 클래스와 인터페이스 선언에 타입 매개변수(type parameter)가 쓰이면, 이를 제네릭 클래스 혹은 제니릭 인터페이스라 합니다. ex) List List 인터페이스는 원소의 타입을 나타내는 타입 매개변수 E를 받습니다. 그래서 이 인터페이스의 완전한 이름은 List지만, 짧게 그냥 List라고도 자주 씁니다. 제네릭 타입(generic type) 제네릭 클래스와 제네릭 인터페이스를 통틀어 지칭하는 말입니다. 매개변수화 타입(parame.. 2023. 8. 28.
[effective java] 제 5장. 제네릭 (들어가기 전에, 용어 정리) 들어가기 전에 제네릭은 자바 5부터 사용할 수 있습니다. 제네릭을 지원하기 전에는 컬렉션에서 객체를 꺼낼 때마다 형변환을 해야 했습니다. 그래서 누군가 실수로 엉뚱한 타입의 객체를 넣어두면, 런타임에 형변환 오류가 나곤 했습니다. 반면, 제네릭을 사용하면 컬렉션이 담을 수 있는 타입을 컴파일러에게 미리 알려주어 컴파일러가 엉뚱한 타입의 객체를 넣으려는 시도를 컴파일 과정에서 차단하여 더 안전하고 명확한 프로그램을 만들 수 있습니다. 또한, 컴파일러가 알아서 형변환 코드를 추가해주기도 합니다. 이번 장에서 제네릭의 이점을 최대한 살리고 단점을 최소화하는 방법을 알아봅시다. 용어 정리 한글 용어 영문 용어 예 매개변수화 타입 parameterized teype List 실제 타입 매개변수 actual typ.. 2023. 8. 28.
[effective java] item 25. 톱 레벨 클래스는 한 파일에 하나만 담으라 결론 한 개의 소스 파일에는 한 개의 톱 레벨 클래스를 담자. 이 규칙을 따르면 한 클래스에 대해 여러 개의 정의를 만들어내는 일이 사라져 안전합니다. 만약, 굳이 여러 개의 톱 레벨 클래스를 한 개의 소스파일에 담고 싶다면 정적 멤버 클래스를 고민해봅시다. 설명 소스 파일 하나에 톱 레벨 클래스를 여러 개 선언해도, 컴파일러는 아무런 경고조차 내지 않습니다. 하지만 이럴 경우 아무런 장점도 없고, 오히려 컴파일 에러를 내고 출력 결과가 달라지는 등 위험을 일으킬 수 있습니다. 왜냐하면 한 클래스를 여러 가지로 정의하게 되게 되고, 그중 어느 것을 사용할지는 어느 소스 파일을 먼저 컴파일하냐에 따라 달라지기 때문입니다. [예제] 한 소스 파일에 2개의 톱 레벨 클래스 Utensil.java : "panc.. 2023. 8. 28.