//컬렉션 분류기 - 오류 ! 이 프로그램은 무엇을 출력할까? public class CollectionClassifier { public static String classify(Set s) { return "집합"; } public static String classify(List lst) { return "리스트"; } public static String classify(Collection c) { return "그 외"; } public static void main(String[] args) { Collection[] collections = { new HashSet, new ArrayList(), new HashMap().values() }; for (Collection c : collect..
API 설계 요령 메서드 이름을 신중히 짓자 편의 메서드를 너무 많이 만들지는 말자 매개변수 목록은 짧게 유지하자 매개변수의 타입으로는 클래스보다는 인터페이스가 더 낫다 boolean 보다는 원소 2개짜리 열거 타입이 낫다 메서드 이름을 신중히 짓자 항상 표준 명명 규칙을 따르자 [아이템68] 이해할 수 있고 같은 패키지의 다른 이름들과 일관되게 지어라 개발자 커뮤니티에서 널리 받아들여지는 이름을 사용 애매하면 자바 라이브러리 API 가이드를 참조 편의 메서드를 너무 많이 만들지 말자 메서드가 너무 많은 클래스는 익히고, 사용하고, 문서화하고, 테스트하고, 유지보수하기 어려움 인터페이스도 메서드가 너무 많으면 구현하는 사람과 사용하는 사람이 모두 힘들음 클래스나 인터페이스는 자신의 기능을 완벽히 수행하는..
자바는 C, C++ 와 다르게 메모리 충돌 오류에서 안전하다. 자바로 작성한 클래스는 항상 그 불변식이 지켜진다. but 클라이언트가 불변식을 깨뜨릴 수 있다고 가정하고 방어적 프로그래밍을 해야함 불변식을 깨뜨리는 예시 public final class Period { private final Date start; private final Date end; public Period(Date strart, Date end) { if (start.compareTo(end) > 0) throw new IllegalArgumentException( start + "가 " + end + "보다 늦다."); this.start = start; this.end = end; } public Date start() { ..
메서드와 생성자 대부분은 입력 매개변수 값이 특정 조건을 만족하길 바란다. 이런 제약은 반드시 문서화하고 메서드 몸체가 시작되기 전에 검사해야한다. 오류는 가능한 빨리 잡아야한다. 매개변수 검사를 제대로 하지 못했을 시 문제점 실패 원자성(failure atomicity)을 어기는 결과 초래 : 메서드 수행 중간에 모호한 예외를 던지며 실패하거나 잘 수행되더라도 잘못된 결과를 반환할 수 있다. 실패 원자성 : 호출된 메서드가 실패하더라도 해당 객체는 호출 전의 상태를 유지해야한다. 매개변수 제약을 어길 시 발생하는 예외 문서화 public이나 protected 메서드는 매개변수 값이 잘못됐을 때 던지는 예외를 문서화해야한다. (@throws 자바독 태그 사용) 보통 IllegalArgumentExcepi..
자바의 동시성 프로그래밍 자바는 동시성 프로그래밍을 지원하려고 항상 노력하였다. 처음부터 스레드, 동기화, wait/notify를 지원 자바5부터는 동시성 컬렉션인 java.util.concurrent 라이브러리와 실행자(Exeuctor) 프레임워크를 지원 자바7부터는 고성능 병렬 분해 프레임워크인 포크-조인(fork-join) 패키지 추가 자바8부터는 스트림의 parallel 메서드로 파이프라인을 병렬 실행할 수 있도록 지원 → 동시성 프로그래밍을 작성하기는 점점 쉬워지고 있지만, 안전성과 응답 가능 상태를 유지하게 작성하기는 여전히 어렵다. 병렬 스트림 파이프라인 프로그래밍에서도 다름 없다. 스트림 병렬화 스트림에서 parallel 사용시에 데이터 소스가 Stream.iterate거나 중간 연산으로 ..
자바7까지는 일련의 원소를 반환하는 메서드의 반환 타입으로 컬렉션 인터페이스나 Iterable, 배열을 써왔다. 그런데, 자바8의 스트림 도입 이후 이 선택이 복잡해졌다. Iterable vs Stream 스트림은 반복을 지원하지 않는다. (반환된 스트림을 for-each 반복 X) 사실 Stream 인터페이스는 Iterable 인터페이스가 정ㅇ의한 추상 메서드를 전부 포함하고, Iterable 인터페이스가 정의한 방식대로 동작 → 그런데도 for-each로 반복 못하는 이유? Stream이 Iterable을 확장(extends)하지 않아서. 스트림을 반복하기 위한 우회 Stream의 iterator 메서드에 메서드 참조를 건네면 스트림을 반복할 수 있을 것 같다. 그러나 다음 코드는 컴파일 오류가 난다..
스트림 패러다임 핵심은 계산을 일련의 변환으로 재구성하는 부분 각 변환 단계는 가능한 한 이전 단계의 결과를 받아 처리하는 순수 함수여야함 순수 함수 : 오직 입력만이 결과에 영향을 주는 함수(다른 가변 상태 참조/변경 x) // 스트림 패러다임을 이해하지 못한 채 API만 사용한 코드 - 따라하지 말 것 Map freq = new HashMap(); try (Stream words = new Scanner(file).tokens()) { words.forEach(word -> { freq.merge(word.toLowerCase(), 1L, Long::sum); // 외부 상태 수정 }); } 위 코드는 스트림 API의 이점을 살리지 못한 스트림을 가장한 반복적 코드이다. 이 코드의 모든 작업은 종단연..
스트림 API 자바8부터는 스트림 API가 다량의 데이터 처리작업을 돕고자 추가되었다. 스트림(stream)은 데이터 원소의 유한 혹은 무한 시퀀스를 뜻함 스트림 파이프라인은 이 원소들로 수행하는 연산단계를 뜻함 스트림 안의 데이터 원소들은 객체 참조나 기본 타입 값(int, long, double 지원) 스트림 파이프라인 소스 스트림에서 시작하여 종단 연산으로 끝남. 그 사이에 중간 연산이 있을 수 있음 중간 연산은 스트림을 어떤 방식으로 변환 한 스트림을 다른 스트림으로 변환 변환된 스트림의 원소 타입은 변환 전과 같을 수도 있고 다를 수도 있음 종단 연산은 마지막 중간 연산이 내놓은 스트림에 최후의 연산을 함 스트림은 지연 평가(lazy evaluation) 된다. 종단연산에 쓰이지 않는 데이터 원..