![](http://i1.daumcdn.net/thumb/C148x148/?fname=https://blog.kakaocdn.net/dn/kW838/btrAssAOCjP/ouSKWT2hMnhPEyriks4ZX1/img.jpg)
람다가 익명 클래스보다 나은 점 중에서 가장 큰 특징은 간결함입니다. 그런데 자바에는 함수 객체를 심지어 람다보다도 더 간결하게 만드는 방법이 있으니, 바로 메서드 참조입니다. 다음 코드는 임의의 키와 Integer 값의 매핑을 관리하는 프로그램의 일부입니다. 이 때 값이 키의 인스턴스 개수로 해석된다면, 이 프로그램은 멀티셋을 구현한 게 됩니다. 이 코드는 키가 맵 안에 없다면 키와 숫자 1을 매핑하고, 이미 있다면 기존 매핑 값을 증가시킵니다. map.merge(key, 1, (count, incr) -> count + incr); 이 코드는 자바 8 때 Map에 추가된 merge 메서드를 사용했습니다. merge 메서드는 키, 값, 함수를 인수로 받으며, 주어진 키가 맵 안에 아직 없다면 주어진 {..
![](http://i1.daumcdn.net/thumb/C148x148/?fname=https://blog.kakaocdn.net/dn/JbfT8/btrAj3t16O8/4elE0yJ7aX3sDqV8H1ekkK/img.jpg)
예전에는 자바에서 함수 타입을 표현할 때 추상 메서드를 하나만 담은 인터페이스(드물게는 추상 클래스)를 사용했습니다. 이런 인터페이스의 인스턴스를 함수 객체라고 하여, 특정 함수나 동작을 나타내는데 썼습니다. 1997년 JDK 1.1이 등장하면서 함수 객체를 만드는 주요 수단은 익명 클래스(아이템 24)가 되었습니다. 다음 코드를 예로 살펴봅시다. 문자열을 길이순으로 정렬하는데, 정렬을 위한 비교 함수로 익명 클래스를 사용합니다. Collections.sort(words, new Comparator() { public int compare(String s1, String s2) { return Integer.compare(s1.length(), s2.length()); } }); 전략(Strategy) ..
![](http://i1.daumcdn.net/thumb/C148x148/?fname=https://blog.kakaocdn.net/dn/dqx7IE/btrz43veYAS/bKZvoZcj0MW5Crz3HmsVu1/img.jpg)
아무 메서드도 담고 있지 않고, 단지 자신을 구현하는 클래스가 특정 속성을 가짐을 표시해주는 인터페이스를 마커 인터페이스(marker interface)라고 합니다. Serializable 인터페이스가 좋은 예입니다. Serializable은 자신을 구현한 클래스의 인스턴스는 ObjectOutputStream을 통해 쓸(write) 수 있다고, 즉 직렬화할 수 있다고 알려줍니다. 마커 애너테이션(아이템 39)이 등장하면서 마커 인터페이스는 구식이 되었다는 이야기가 있습니다. 하지만 이것은 사실이 아니며 마커 인터페이스는 두 가지 면에서 마커 애너테이션보다 낫습니다. [1]. 마커 인터페이스는 이를 구현한 클래스의 인스턴스들을 구분하는 타입으로 쓸 수 있다. 마커 인터페이스는 어엿한 타입이기 때문에, 마커..
![](http://i1.daumcdn.net/thumb/C148x148/?fname=https://blog.kakaocdn.net/dn/btMhi8/btrz7i5Qh06/UmBcseMQEa1BW6k6H7TgI0/img.jpg)
자바가 기본으로 제공하는 애너테이션 중 보통의 프로그래머에게 가장 중요한 것은 @Override일 것입니다. @Override는 메서드 선언에만 달 수 있으며, 이 애너테이션이 달렸다는 것은 상위 타입의 메서드를 재정의했음을 뜻합니다. 이 애너테이션을 일관되게 사용하면 여러 가지 악명 높은 버그들을 예방해줍니다. 다음의 Bigram 프로그램을 살펴봅시다. 이 클래스는 바이그램, 즉 여기서는 영어 알파벳 2개로 구성된 문자열을 표현합니다. public class Bigram { private final char first; private final char second; public Bigram(char first, char second) { this.first = first; this.second = s..
![](http://i1.daumcdn.net/thumb/C148x148/?fname=https://blog.kakaocdn.net/dn/AdLLa/btrz5nUwWpa/Eh1hvKSvo8zlbsq6vMUaF0/img.jpg)
전통적으로 도구나 프레임워크가 특별히 다뤄야 할 프로그램 요소에는 딱 구분되는 명명 패턴을 적용해왔습니다. 예컨대 테스트 프레임워크인 JUnit은 버전 3까지 테스트 메서드 이름을 test로 시작하게끔 했습니다. 효과적인 방법이지만 단점도 큽니다. [1]. 오타가 나면 안 된다. 실수로 이름을 tsetSafetyOverride로 지으면 JUnit 3은 이 메서드를 무시하고 지나치기 때문에 개발자는 이 테스트가 통과했다고 오해할 수 있습니다. [2]. 올바른 프로그램 요소에서만 사용되리라 보증할 방법이 없다는 것이다. 예컨대 (메서드가 아닌) 클래스 이름을 TestSafetyMechanisms로 지어 JUnit에 던져줬다고 해봅시다. 개발자는 이 클래스에 정의된 테스트 메서드들을 수행해주길 기대하겠지만 J..
![](http://i1.daumcdn.net/thumb/C148x148/?fname=https://blog.kakaocdn.net/dn/wRoX1/btrz4M1vfpt/wigFpl3ymKIIChZFnpJyjk/img.jpg)
열거 타입은 거의 모든 상황에서 타입 안전 열거 패턴보다 우수합니다. 단, 예외가 하나 있으니, 타입 안전 열거 패턴은 확장할 수 있으나 열거 타입은 그럴 수 없다는 점입니다. 달리 말하면, 타입 안전 열거 패턴은 열거한 값들을 그대로 가져온 다음 값을 더 추 가하여 다른 목적으로 쓸 수 있는 반면, 열거 타입은 그렇게 할 수 없다는 뜻입니다. 실수로 이렇게 설계한 것은 아닙니다. 사실 대부분 상황에서 열거 타입을 확장하는 건 좋지 않은 생각입니다. 기반 타입과 확장된 타입들의 원소 모두를 순회할 방법도 마땅치 않습니다. 마지막으로, 확장성을 높이려면 고려할 요소가 늘어나 설계와 구현이 더 복잡해집니다. 그런데 확장할 수 있는 열거 타입이 어울리는 쓰임이 최소한 하는 있습니다. 바로 연산 코드(opera..
![](http://i1.daumcdn.net/thumb/C148x148/?fname=https://blog.kakaocdn.net/dn/kTF7c/btrzMJpf3h4/JnYuxbNN2co9w0ICoIpw61/img.jpg)
이따금 배열이나 리스트에서 원소를 꺼낼 때 ordinal 메서드(아이템 35)로 인덱스를 얻는 코드가 있습니다. 식물을 간단히 나타낸 다음 클래스를 예로 살펴봅시다. class Plant { enum LifeCycle { ANNUAL, PERENNIAL, BIENNIAL } final String name; final LifeCycle lifeCycle; Plant(String name, LifeCycle lifeCycle) { this.name = name; this.lifeCycle = lifeCycle; } @Oveeride public String toString() { return name; } } 이제 정원에 심은 식물들을 배열 하나로 관리하고, 이들을 생애주기별로 묶어봅시다. 생애주기별로 총..
- Total
- Today
- Yesterday
- 프로그래머스
- 이펙티브 자바
- BOJ
- 디자인 패턴
- 알고리즘
- Olympiad
- 디자인패턴
- MSA
- 클린 아키텍처
- 이팩티브 자바
- JPA
- Effective Java
- AWS
- 정규표현식
- kkoon9
- Java
- 코테
- node.js
- programmers
- kotest
- 테라폼
- Spring Boot
- BAEKJOON
- 객체지향
- Spring
- 백준
- 클린 코드
- Algorithm
- C++
- Kotlin
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |