본문 바로가기

Java

(34)
[Effectiva Java][아이템42] 익명 클래스보다는 람다를 사용하라 [코드 42-1] 익명 클래스의 인스턴스를 함수 객체로 사용한 예시 Collectorions.sort(words, new Comparator(){ public int compare(String s1, String s2) { return Integer.compare(s1.length(), s2.length()); } }); 과거 객체 지향 디자인 패턴에서는 익명 클래스면 충분했지만, 코드가 너무 길기 때문에 함수형 인터페이스에는 적절하지 않았다. 자바8에서부터 함수형 인터페이스(추상 메서드 하나를 갖는 인터페이스)를 사용할 수 있게 되었다. Collections.sort(words, (s1, s2) -> Integer.compare(s1.length(), s2.length())); // 람다 코드가 훨씬 ..
[Effectiva Java][아이템41] 정의하려는 것이 타입이라면 마커 인터페이스를 사용하라 (마커 인터페이스, 마커 애너테이션의 적절한 쓰임) 마커 인터페이스란, 인터페이스 내에 아무 메서드가 없고 자신을 구현하는 클래스가 특정 속성을 가짐을 표시해주는 인터페이스이다. 대표적으로 Serializable 인터페이스가 있다. 마커 인터페이스 vs 마커 애너테이션 마커 인터페이스보다 더 나중에 등장한 마커 애너테이션이 있다. 1. 마커 인터페이스는 이를 구현한 클래스의 인스턴스들을 구분하는 타입으로 사용할 수 있다. 2. 마커 인터페이스가 적용대상을 더 정밀하게 지정할 수 있다. 적용 대상(@Target)을 ElementType.TYPE으로 선언한 애너테이션은 모든 타입(클래스, 인터페이스, enum, 애너테이션)에 달 수 있다. 이는 부착할 수 있는 타입을 더 세밀하게 지정하지 못한다는 뜻이 될수도 있다. 특정 인터페이스를 구현한 클래스에만 적용하..
[Effectiva Java][아이템40] @Override 애너테이션을 일관되게 사용하라 아래 예시는 @Override를 실수로 빼먹었을 때 발생할 수 있는 오류이다. [코드 40-1] 영어 알파벳 2개로 구성된 문자열을 표현하는 클래스 public class Bigram { private final char first; private final char second; public Bigram(char first, char second) { this.first = first; this.second = second; } // 재정의가 되지 않음. 오버로딩 public boolean equals(Bigram b) { retrun b.first = first && b.second = second; } // 재정의가 되지 않음. 오버로딩 public int hashCode() { return 31*..
[Effectiva Java][아이템37] ordinal 인덱싱 대신 EnumMap을 사용하라 아이템37. ordinal 인덱싱 대신 EnumMap을 사용하라 WHY: oridnal 인덱싱은 유지보수가 어렵다. 예제1)식물를 생애주기별로 분류하기 - ordinal버전 Set[] plantsByLifeCycle = (Set[]) new Set(Plant.LifeCycle.values().length]; // ㄷ3ㄱㅐㅡㅣ ㅈㅣㅂ for (int i = 0; i < plantsByLifeCycle.lengh; i++) plantsByLifeCycle[i] = new HashSet(); for (Plant p : garden) { plantsByLifeCycle[p.lifeCycle.ordinal()].add(p); } for (int i = 0; i < plantsByLifeCycle.length; i..
[Effective Java][아이템36] 열거정수를 집합으로 사용해야 하는 경우 - EnumSet 아이템36. 비트 필드 대신 EnumSet을 사용하라 WHY: 비트필드(bit field)의 단점을 보완할 수 있다. 열거 정수를 집합으로 사용해야 하는 경우, 열거 정수를 비트값으로 초기화 & OR연산으로 집합을 생성했다. 이를 비트 필드(bit field)라고 부른다 예시1) 비트 필드 열거 상수 (예전 기법) public class Text { public static final int STYLE_BOLD = 1
[Effective Java][아이템35] ordinal 메서드를 잘못사용한 사례와 해결방법 아이템35. ordinal 메서드 대신 인스턴스 필드를 사용하라 enum에서 제공하는 ordinal메서드를 프로그래머가 잘못사용하는 경우가 많다. WHY: ordinal 메서드의 개념을 착각하기 쉽다. enum에서 제공하는 ordinal메서드는 enum 상수가 그 열거타입에서 몇 번째 위치인지를 알려주는 메서드이다. 때문에, enum상수와 연결된 정숫값이 필요하면 쉽게 사용하려고 한다. . . 눈치 챘겠지만 이는 좋은 방법이 아니다. 예시1) [BAD] enum에 oridnal()을 사용하여 합주자 수를 구하는 예시 public enum Ensemble { SOLO, DUET, TRIO, QUARTET, QUINTET, SEXTET, SEPTET, OCTET, NONET, DECTET; // oridna..
[Effective Java][아이템34] ENUM 기본 사용법과 여러 구현 케이스 소개 아이템34. int상수 대신 열거 타입을 사용하라 WHY: 정수 열거 패턴의 단점을 보완할 수 있다. 정수 상수를 static final로 선언해서 사용. public static final int APPLE_FUJI = 0; public static final int APPLE_PIPPIN = 1; public static final int APPLE_SMITH = 2; public static final int ORANGE_NAVEL = 0; public static final int ORANGE_TEMPLE = 1; public static final int ORANGE_BLOOD = 2; 단점 1) 타입 안전성을 보장할 수 없다. // 향긋한 오렌지 향의 사과 소스 int i = (APPLE_FU..
[Effective Java] 아이템32. 제네릭과 가변인수를 함께 쓸 때는 신중하라 1. What: 제네릭에 가변인수를 쓰는 예시 2. Why: 가변인수와 제너릭을 함께쓰면 타입안정성이 보장되지 않는다. static void dangerous(List... stringLists) { // (1) List intList = List.of(42); // (2) Object[] objects = stringLists; // (3) objects[0] = intList; // (4) 힙 오염 발생 String s = stringLists[0].get(0); // (5) ClassCastException } 가변인수 메서드를 호출하면 가변인수를 담기위한 배열이 자동으로 하나 만들어진다. -> 위 예시에서는 List[] stringLists이다.// (1) 이 배열이 Obejct[]에 저장될 수 ..