java

언어/JAVA

[Effective Java] 람다보다는 메서드 참조를 사용하라

아이템 43 : 람다보다는 메서드 참조를 사용하라 람다가 익명 클래스보다 나은 점 중에서 가장 큰 특징은 간결함이다. 그런데 자바에는 함수 객체를 심지어 람다보다도 간결하게 만드는 방법이 있으니, 바로 메서드 참조다. 메서드 참조의 유형은 다섯 가지가 있다. 그 중 두 가지는 인스턴스 메서드를 참조하는 유형이다. 첫 번째, 정적 메서드를 가리키는 메서드 참조이다. 두 번째, 수신 객체를 특정하는 한정적 인스턴스 메서드 참조이다. 세 번째, 수신 객체를 특정하지 않는 비한정적 인스턴스 메서드 참조이다. 네 번째, 클래스 생성자를 가리키는 메서드 참조이다. 다섯 번째, 배열 생성자를 가리키는 메서드 참조이다. 핵심 정리 메서드 참조는 람다의 간단명료한 대안이 될 수 있다. 메서드 참조 쪽이 짧고 명확하다면 ..

언어/JAVA

[Effective Java] 익명 클래스보다는 람다를 사용하라

아이템 42 : 익명 클래스보다는 람다를 사용하라 예전에는 자바에서 함수 타입을 표현할 때 추상 메서드를 하나만 담은 인터페이스(드물게는 추상 클래스)를 사용했다. 이런 인터페이스의 인스턴스를 함수 객체라고 하여 특정 함수나 동작을 나타내는 데 썼다. 1997년 JDK 1.1이 등장하면서 함수 객체를 만드는 주요 수단은 익명 클래스가 되었다. 아래 코드는 문자열을 길이순으로 정렬하는데, 정렬을 위한 비교 함수로 익명 클래스를 사용한다. 1 2 3 4 5 Collections.sort(words, new Comparator()) { public int compare(String s1, String s2) { return Integer.compare(s1.length(), s2.length()); } });..

언어/JAVA

[Effective Java] 정의하려는 것이 타입이라면 마커 인터페이스를 사용하라

아이템 41 : 정의하려는 것이 타입이라면 마커 인터페이스를 사용하라 아무 메서드도 담고 있지 않고, 단지 자신을 구현하는 클래스가 특정 속성을 가짐을 표시해주는 인터페이스를 마커 인터페이스라 한다. 마커 애너테이션이 등장하면서 마커 인터페이스는 구식이 되었다는 이야기를 들어보았을 것이다. 하지만 사실이 아니다. 마커 인터페이스는 두 가지 면에서 마커 애너테이션보다 낫다. 첫 번째, 마커 인터페이스는 이를 구현한 클래스의 인스턴스들을 구분하는 타입으로 쓸 수 있으나, 마커 애너테이션은 그렇지 않다. 마커 인터페이스는 어엿한 타입이기 때문에, 마커 애너테이션을 사용했다면 런타임에야 발견될 오류를 컴파일타임에 잡을 수 있다. 두 번째, 적용 대상을 더 정밀하게 지정할 수 있다는 것이다. 반대로 마커 애너테이..

언어/JAVA

[Effective Java] @Override 애너테이션을 일관되게 사용하라

아이템 40 : @Override 애너테이션을 일관되게 사용하라 자바가 기본으로 제공하는 애너테이션 중 보통의 프로그래머에게 가장 중요한 것은 @Override일 것이다. @Override는 메서드 선언에만 달 수 있으며, 이 애너테이션이 달렸다는 것은 상위 타입의 메서드를 재정의했음을 뜻한다. 이 애너테이션을 일관되게 사용하면 여러 가지 악명 높은 버그들을 예방해준다. 상위 클래스의 메서드를 재정의하려는 모든 메서드에 @Override 애너테이션을 달자. 예외는 한 가지뿐이다. 구체 클래스에서 상위 클래스의 추상 메서드를 재정의할 때는 굳이 @Override를 달지 않아도 된다. 구체 클래스인데 아직 구현하지 않은 추상 메서드가 남아 있다면 컴파일러가 그 사실을 바로 알려주기 때문이다. @Overrid..

언어/JAVA

[Effective Java] 명명 패턴보다 애너테이션을 사용하라

아이템 39 : 명명 패턴보다 애너테이션을 사용하라 전통적으로 도구나 프레임워크가 특별히 다뤄야 할 프로그램 요소에는 딱 구분되는 명명 패턴을 적용해왔다. 예컨데 테스트 프레임워크인 JUnit은 버전 3까지 테스트 메서드 이름을 test로 시작하게끔 했다. 효과적인 방법이지만 단점도 크다. 첫 번째, 오타가 나면 안 된다. 실수로 이름을 testSafetyOverride로 지으면 JUnit 3은 이 메서드를 무시하고 지나치기 때문에 개발자는 이 테스트가 통과했다고 오해할 수 있다. 두 번째, 올바른 프로그램 요소에서만 사용되리라 보증 할 방법이 없다는 것이다. 클래스 이름을 TestSafetyMechanisms로 지어 JUnit에 던져줬다고 해보자. 개발자는 이 클래스에 정의된 테스트 메서드들을 수행해주..

언어/JAVA

[Effective Java] 확장할 수 있는 열거 타입이 필요하면 인터페이스를 사용하라

아이템 38 : 확장할 수 있는 열거 타입이 필요하면 인터페이스를 사용하라 열거 타입은 거의 모든 상황에서 타입 안전 열거 패턴보다 우수하다. 단, 예외가 하나 있으니, 타입 안전 열거 패턴은 확장할 수 있으나 열거 타입은 그럴 수 없다는 점이다. 달리 말하면, 타입 안전 열거 패턴은 열거한 값들을 그대로 가져온 다음 값을 더 추가하여 다른 목적으로 쓸 수 있는 반면, 열거 타입은 그렇게 할 수 없다는 뜻이다. 사실 대부분 상황에서 열거 타입을 확장하는 건 좋지 않은 생각이다. 확장한 타입의 원소는 기반 타입의 원소로 취급하지만 그 반대는 성립하지 않는다면 이상하지 않은가! 기반 타입과 확장된 타입들의 원소 모두를 순회할 방법도 마땅치 않다. 마지막으로, 확장성을 높이려면 고려할 요소가 늘어나 설계와 구..

언어/JAVA

[Effective Java] ordinal 인덱싱 대신 EnumMap을 사용하라

아이템 37 : ordinal 인덱싱 대신 EnumMap을 사용하라 이따금 배열이나 리스트에서 원소를 꺼낼 때 ordinal 메서드로 인덱스를 얻는 코드가 있다. ordinal()을 배열 인덱스로 사용할 경우 동작은 하지만 문제가 발생할 것이다. 배열은 제네릭과 호환되지 않으니 비검사 형번환을 수행해야 하고 깔끔히 컴파일되지 않을 것이다. 이를 해결할 수 있는 방안이 있다. 여기서 배열은 실질적으로 열거 타입 상수를 값으로 매핑하는 일을 한다. 그러니 Map을 사용할 수 있다. 열거 타입을 키로 사용하도록 설계된 아주 빠른 Map 구현체가 존재한다. 바로 EnumMap이다. EnumMap을 사용하면 ordinal을 쓸때보다 짧고 명료하고 안전하다. 안전하지 않은 형변환은 쓰지 않고, 맵의 키인 열거 타입..

언어/JAVA

[Effective Java] 비트 필드 대신 EnumSet을 사용하라

아이템 36 : 비트 필드 대신 EnumSet을 사용하라 열거한 값들이 주로 단독이 아닌 집합으로 사용될 경우, 예전에는 각 상수에 서로 다른 2의 거듭제곱 값을 할당한 정수 열거 패턴을 사용해 왔다. 1 2 3 4 5 6 7 8 9 public class Text { public static final int STYLE_BOLD = 1

언어/JAVA

[Effective Java] ordinal 메서드 대신 인스턴스 필드를 사용하라

아이템 35 : ordinal 메서드 대신 인스턴스 필드를 사용하라 대부분의 열거 타입 상수는 자연스럽게 하나의 정숫값에 대응된다. 그리고 모든 열거 타입은 해당 상수가 그 열거 타입에서 몇 번째 위치인지를 반환하는 ordinal이라는 메서드를 제공한다. 다음 코드는 합주단의 종류를 연주자가 1명인 솔로부터 10명인 디텍트까지 정의한 열거 타입이다. 1 2 3 4 5 6 public enum Ensemble { SOLO, DUET, TRIO, QUARTET, QUINTET, SEXTET, SEPTET, OCTET, NONET, DECTET; public int numberOfMusicians() {return ordinal() + 1; } } Colored by Color Scripter 동작은 하지만 ..

언어/JAVA

[Effective Java] int 상수 대신 열거 타입을 사용하라

아이템 34 : int 상수 대신 열거 타입을 사용하라 열거 타입은 일정 개수의 상수 값을 정의한 다음, 그 외의 값은 허용하지 않는 타입이다. 정수 열거 패턴 기법에는 단점이 많다. 타입 안전을 보장할 방법이 없으며 표현력도 좋지않다. 오렌지를 건네야 할 메서드에 사과를 보내고 동등 연산자(==)로 비교하더라도 컴파일러는 아무런 경고 메시지를 출력하지 않는다. 정수 열거 패턴을 사용한 프로그램은 깨지기 쉽다. 평범한 상수를 나열한 것뿐이라 컴파일하면 그 값이 클라이언트 파일에 그대로 새겨진다. 따라서 상수의 값이 바뀌면 클라이언트도 반드시 다시 컴파일해야 한다. 다시 컴파일하지 않은 클라이언트는 실행이 되더라도 엉뚱하게 동작할 것이다. 정수 상수는 문자열로 출력하기가 다소 까다롭다. 그 값을 출력하거나..

지나가던 개발자
'java' 태그의 글 목록