Effective Java (63) 썸네일형 리스트형 [Effective Java] 아이템 54 - null이 아닌, 빈 컬렉션이나 배열을 반환하라 private final List cheesesInStock = ...; /** * @return 매장 안의 모든 치즈 목록을 반환한다. * 단, 재고가 하나도 없다면 null을 반환한다. */ public List getCheeses() { return cheesesInStock.isEmpty() ? null : new ArrayListo( cheesesInStock); } → 클라이언트는 null 처리 코드를 추가로 작성해야 하며, 처리 코드가 없을 경우 오류가 발생할 수 있다. 빈 컨테이너를 할당하는 데도 비용이 드니 null을 반환하는 쪽이 낫다는 주장도 있지만, 성능 분석 결과 빈 컨테이너를 할당하는 것이 성능 저하의 주범이라고 확인되지 않는 한, 이 정도의 성능 차이는 신경 쓸 수준이 못 된다.. [Effective Java] 아이템 53 - 가변인수는 신중히 사용하라 가변인수(varargs) 메서드는 명시한 타입의 인수를 0개 이상 받을 수 있다. 가변인수 메서드를 호출하면, 가장 먼저 인수의 개수와 길이가 같은 배열을 만들고 인수들을 이 배열에 저장하여 가변인수 메서드에 건네준다. static int sum(int... args) { int sum = 0; for (int arg : args) sum += arg; return sum; } 위의 경우와 다르게 밑의 코드처럼 인수가 1개 이상이어야 할 때도 있다. static int min(int... args) { if (args.length = 0) throw new IllegalArgumentException("인수가 1개 이상 필요합니다."); int min = args[0]; for (int i = 1; i .. [Effective Java] 아이템 52 - 다중정의는 신중히 사용하라 다중정의(overloading) : 같은 이름의 메소드를 중복하여 정의하는 것을 말한다. 어느 메서드를 호출할 지 컴파일타임에 정해진다. → 정적으로 메서드 선택 즉, 객체의 런타임 타입은 전혀 중요하지 않다. 오직 매개변수의 컴파일타임 타입에 의해 이뤄진다. 재정의(overriding) : 상위 클래스가 정의한 것과 똑같은 시그니처의 메서드를 하위 클래스에서 다시 정의한 것을 말한다. 런타임 타입에 따라 어떤 메서드를 호출할지 정해진다. → 동적으로 메서드 선택 public class Collectionclassifier { public static String classify(Set s) { return "집합"; } public static String classify(List 1st) { retu.. [Effective Java] 아이템 51 - 메서드 시그니처를 신중히 설계하라 메서드 이름을 신중히 짓자. 항상 표준 명명 규칙을 따르며 같은 패키지에 속한 다른 이름들과 일관되게 짓는게 최 우선이다. 다음 목표는 개발자 커뮤니티에서 널리 쓰이는 이름을 사용하고 너무 긴 이름은 피하자 편의 메서드를 너무 많이 만들지 말자. 모든 메서드는 각자 자신의 소임을 다해야 한다. 메서드가 너무 많은 클래스나 인터페이스는 익히고, 사용하고, 유지보수하기 어렵다. 클래스나 인터페이스는 자신의 각 기능을 완벽히 수행하는 메서드로 제공해야 한다. 확신이 서지 않으면 만들지 말자. 매개변수 목록은 짧게 유지하자. 매개 변수목록이 너무 많다면 전부 기억하기 어렵고 API문서를 옆에 끼고 개발해야 한다. 특히나 같은 타입의 매개변수가 여러개 나오는 경우가 가장 해롭다. 순서를 기억하기 어렵고 헷갈려서 .. [Effective Java] 아이템 50 - 적시에 방어적 복사본을 만들라 Java는 포인터를 사용하는 언어와 달리 메모리 충돌 오류에서 안전하지만 클라이언트가 우리가 작성한 클래스의 불변식을 깨려고 노력한다는 것을 가정에 두고 방어적으로 프로그래밍 해야 한다. 기간을 표현하는 클래스를 보자 class Period { private final Date start; private final Date end; public Period(Date start, Date end) { if(start.compareTo(end) > 0) { throw new IllegalArgumentException(start + " after " + end); } this.start = start; this.end = end; } public Date start() { return start; } pub.. [Effective Java] 아이템 49 - 매개변수가 유효한지 검사하라 메서드와 생성자 대부분 입력 매개변수의 값이 특정 조건을 만족하기를 바란다. 이런 제약은 문서화가 필요하며 메서드 몸체가 시작되기 전에 검사해야한다. 이는 "오류는 가능한 빨리(발생한 곳에서) 잡아야한다."는 일반 원칙의 사례이기도 하다. 메서드 몸체가 실행되기 전에 매개변수를 확인하면 즉각적이고 깔끔한 방식으로 예외를 던질 수 있다. 반대로 매개변수 검사를 제대로 수행하지 못하면 아래와 같은 문제가 발생한다. 메서드가 수행되는 중간에 모호한 예외를 던지며 실패한다. 메서드는 잘 수행되지만 잘못된 결과를 반환한다. 메서드는 잘 수해되지만 어떤 객체를 이상한 상태로 만들어 놓아 알수 없는 시점에 이 메서드와 관련없는 오류를 낸다. 즉 매개변수 검사에 실패하면 실패 원자성(failure atomicity)를.. [Effective Java] 아이템48 - 스트림 병렬화는 주의해서 적용하라 자바 8 버전 이후로 parallel 메서드만 호출하면 파이프라인을 병렬 실행할 수 있는 스트림을 지원하고 있다. 이처럼 동시성 프로그램을 작성하기 쉬워졌지만, 프로그램 작성자는 그에대한 안전성과 응답가능 상태를 유지하기 위해 노력해야 한다. 병렬 스트림 파이프라인 프로그래밍도 예외는 아니다. public static void main(String[] args) { primes().map(p -> TWO.pow(p.intValueExact()).subtract(ONE)) .filter(mersenne -> mersenne.isProbablePrime(50)) .limit(20) .forEach(System.out::println); } static Stream primes(){ return Stream... [Effective Java] 아이템 47 - 반환 타입으로는 스트림보다 컬렉션이 낫다 ■ 반환타입 선택 원소 시퀀스, 즉 일련의 원소를 반환하는 메서드는 많다. Collection, List, Set과 같은 컬렉션 인터페이스, 혹은 Iterable이나 배열을 사용했다. 자바 8에서는 스트림이 도입되면서 선택지가 복잡해졌다. 스트림은 반복(Iteration)을 지원하지 않는다. 따라서 스트림과 반복을 알맞게 조합해야 좋은 코드가 나온다. 여기서 재밌는 사실 하나는 Stream인터페이스는 Iterable 인터페이스의 추상 메서드를 모두 정의해 놓았지만 Iterable을 확장하지 않았다는 문제가 있다. 예제 1 : Stream → Iterable adaptor 아래의 코드는 자바 타입 추론의 한계로 컴파일되지 않는다. public class Item47 { public static void m.. [Effective Java] 아이템 46 - 스트림에서는 부작용 없는 함수를 사용하라 * 스트림에 대한 개념 스트림: 데이터 원소의 유한 또는 무한 시퀀스 스트림 파이프라인: 원소들을 수행하는 연산 단계를 표현하는 개념 스트림은 그저 API가 아니라 함수형 프로그래밍에 기초한 패러다임이다. 그래서 이 패러다임까지 함께 받아들여야 한다. 스트림 패러다임의 핵심은 계산을 일련의 변환으로 재구성 하는 부분이다. 이때 각 변화 단계는 가능한 한 이전 단계의 결과를 받아 처리하는 순수 함수여야 한다. 순수 함수란 오직 입력만이 결과에 영향을 주는 함수를 말한다. 다른 가변 상태를 참조하지 않고, 함수 스스로도 다른 상태를 변경하지 않는다. 이렇게 하려면 (중간 단계든 종단 단계든) 스트림 연산에 건네는 함수 객체는 모두 부작용(side effect)이 없어야 한다. 다양한 스트림 연산 for Ea.. [Effective Java] 아이템 45 - 스트림은 주의해서 사용하라 스트림 API 핵심 1. 스트림은 데이터 원소의 유한 혹은 무한 시퀀스를 뜻한다. 2. 스트림 파이프 라인은 이 원소들이 수행하는 연산 단계를 표현하는 개념이다. 스트림의 원소 어디로부터든 올 수 있다. 대표적으로 컬렉션, 배열, 파일, 정규표현식 패턴 매처, 난수 생성기, 혹은 다른 스트림등이 존재 스트림 안의 데이터 원소 객체 참조나 기본 타입 값 기본 타입 값으로 int, long, double 3가지만 지원 스트림 파이프라인 특징 스트림 파이프라인은 소스스트림 -> (중간연산) -> 종단연산 으로 이루어진다. 각 중간 연산은 스트림을 어떠한 방식으로 변환(transform)한다. 중간연산을 합친 다음에 합쳐진 중간연산을 최종 연산으로 한번에 처리 -> Lazy evaluation 평가는 종단 연산.. 이전 1 2 3 4 5 ··· 7 다음