✔️ 정적 팩터리 메서드(Static Factory Method) 란?그 클래스의 인스턴스를 반환하는 단순한 정적 메서드참고)정적 팩터리 메서드는 디자인 패턴에서의 팩터리 메서드 (Factory Method)와 다르다.디자인 패턴 중 이와 일치하는 패턴은 없다.✔️ 장
들어가며..정적 팩터리와 생성자에는 똑같은 제약 사항이 하나 있다. 바로 선택적 매개변수가 많을 때 적절히 대응하기 어렵다는 점이다.지금부터 선택 매개변수가 많을 때 취할 수 있는 대안을 알아보자!먼저 점층적 생성자 패턴이 있다.이 패턴은 필수 매개변수만 생성자부터,
인스턴스를 오직 하나만 생성할 수 있는 클래스를 말한다.싱글턴의 전형적인 예로는 함수와 같은 무상태(stateless) 객체나 설계상 유일해야 하는 시스템 컴포넌트를 들 수 있다.싱글턴을 만드는 방식은 3가지가 있다.public static final 필드 방식 (pr
이따금 단순히 정적 메서드와 정적 필드만을 담은 클래스를 만들고 싶을 때가 있을 것이다.이렇게 정적 멤버만 담은 클래스는 인스턴스로 만들어 쓰려고 설계한 것이 아니다.따라서 이러한 클래스의 인스턴스화를 막아야하는데, 생성자를 명시하지 않으면 컴파일러가 자동으로 기본 생
많은 클래스가 하나 이상의 자원에 의존한다.이런 클래스는 정적 유틸리티 클래스로 구현하거나 싱글턴으로 구현할 수 있는데, 둘 다 그리 좋지 않은 방법이다. 다음의 예시를 보자.두 방식 모두 dictionary를 단 하나 사용한다고 가정한다는 점에서 좋아 보이지 않는다
똑같은 기능의 객체를 매번 생성하기보다는 객체 하나를 재사용하는 편이 나을 때가 많다. 1번 코드의 경우, 실행될 때마다 String 인스턴스를 새로 만든다. 생성자에 넘겨진 "bikini" 자체가 이 생성자가 만들어내는 String과 기능적으로 완전히 똑같으므로,
가비지 컬렉션 언어에서는 메모리 누수를 찾기가 아주 까다롭다.가비지 컬렉터는 객체 참조 하나를 살려두면 그 객체 뿐만 아니라 그 객체가 참조하는 모든 객체(그리고 또 그 객체들이 참조하는 모든 객체...)를 회수해가지 못한다. 그래서 단 몇 개의 객체가 매우 많은 객
자바는 두 가지 객체 소멸자를 제공한다.1️⃣ 첫 번째는 finalizer 다. finalizer는 예측할 수 없고, 상황에 따라 위험할 수 있어 일반적으로 불필요하다.2️⃣ 두 번째는 cleaner 다. finalizer는 오동작, 낮은 성능, 이식성 문제가 있었기
자바에는 InputStream, OutputStream, java.sql.Connection과 같이 close 메서드를 호출해 직접 닫아줘야 하는 자원이 많다. 그런데 자원 닫기는 클라이언트가 놓치기 쉬워 성능 문제로 이어질 수 있다.그렇다면 자원이 제대로 닫히도록 보
equals 메서드는 재정의하기 쉬워 보이지만 곳곳에 함정이 도사리고 있다. 따라서 재정의가 필요하지 않은 경우에는 재정의하지 않는 것이 최선의 선택이다.값을 표현하는 게 아니라 동작하는 개체를 표현하는 클래스Thread 와 같은 클래스가 좋은 예시다.equals가 실
equals를 재정의한 클래스 모두에서 hashCode도 재정의해야 한다. 그렇지 않으면 hashCode 일반 규약을 어기게 되어 해당 클래스의 인스턴스를 HashMap이나 HashSet 과 같은 컬렉션의 원소로 사용할 때 문제를 일으킬 것이다. ✔️ hashCode
Object의 기본 toString 메서드가 작성한 클래스의 적합한 문자열을 반환하는 경우는 거의 없다.이 메서드는 단순히 클래스\_이름@16진수로\_표시한\_해시코드 를 반환할 뿐이다.toString의 일반 규약에 따르면 '간결하면서 사람이 읽기 쉬운 형태의 유익한
Cloneable은 복제해도 되는 클래스임을 명시하는 용도의 '믹스인 인터페이스(mixin interface, 아이템 20)'지만, 의도한 목적을 제대로 이루지 못했다. 가장 큰 문제는 clone 메서드가 선언된 곳이 Cloneable이 아닌 Object이고, 그 마저
이번에는 Comparable 인터페이스의 유일한 메서드인 compareTo에 대하여 알아보자.compareTo 는 두 가지만 빼면 Object의 equals와 같다.첫 번째, compareTo 는 단순 동치성 비교에 더해 순서까지 비교할 수 있다.두 번째, compar
잘 설계된 컴포넌트는 모든 내부 구현을 완벽히 숨겨, 구현과 API를 깔끔히 분리한다. 오직 API를 통해서만 다른 컴포넌트와 소통하며 서로의 내부 동작 방식에는 전혀 개의치 않는다. 이러한 정보 은닉 혹은 캡슐화라고 하는 개념은 소프트웨어 설계의 근간이 되는 원리다.
위의 클래스는 데이터 필드를 직접 접근할 수 있어, 캡슐화의 이점을 제공하지 못 한다.API를 수정하지 않고는 내부 표현을 바꿀 수 없고, 불변식을 보장할 수 없으며, 외부에서 필드에 접근할 때 부수 작업을 수행할 수도 없다.위와 같이 필드는 private으로 하고,
String기본 타입의 박싱된 클래스들ex) Integer, Long, DoubleBigIntegerBigDecimal객체의 상태를 변경하는 메서드(변경자)를 제공하지 않는다.클래스를 확장할 수 없도록 한다.→ 2가지 방법이 있다. (클래스 상속 방지하는 방법 참고)모
이번 아이템에서 논하는 상속은 클래스가 다른 클래스를 확장하는 구현 상속을 말한다.클래스가 인터페이스를 구현하거나 인터페이스가 다른 인터페이스를 확장하는 인터페이스 상속과는 무관하다.메서드 호출과 달리 상속은 캡슐화를 깨뜨린다.상위 클래스가 릴리스 때 내부 구현이 달라
상속용 클래스는 재정의할 수 있는 메서드들을 내부적으로 어떻게 이용하는지 문서로 남겨야 한다.재정의 가능 메서드를 호출할 수 있는 모든 상황을 문서로 남겨야 한다. 💡 재정의 가능 메서드 : public과 protected 메서드 중 final이 아닌 모든 메서드.
자바가 제공하는 다중 구현 메커니즘은 인터페이스와 추상 클래스 2가지다.두 메커니즘 모두 인스턴스 메서드를 구현 형태로 제공할 수 있다.둘의 가장 큰 차이는 추상 클래스가 정의한 타입을 구현하는 클래스는 반드시 추상 클래스의 하위 클래스가 되어야 한다는 점이다.자바는
자바 8 전에는 기존 구현체를 깨뜨리지 않고는 인터페이스에 메서드를 추가할 방법이 없었으나,자바 8 부터는 디폴트 메서드가 소개되면서 기존 인터페이스에 메서드를 추가할 수 있게 되었다.그러나 이렇게 추가된 디폴트 메서드가 모든 기존 구현체들과 매끄럽게 연동되리라는 보장
인터페이스는 자신을 구현할 클래스의 인스턴스를 참조할 수 있는 타입 역할을 한다.인터페이스는 오직 이 용도로만 사용해야 한다.인터페이스를 타입을 정의하는 용도로 사용하지 않은 대표적인 예로 상수 인터페이스를 들 수 있다.상수 인터페이스란, 메서드 없이 상수를 뜻하는 s
열거 타입 선언, 태그 필드, switch 문 등 쓸데없는 코드가 많다.여러 구현이 한 클래스에 혼합되어 있어 가독성도 나쁘다.오류를 내기 쉽다: 필드를 final로 선언하려면 해당 의미에 쓰이지 않는 필드들까지 생성자에서 초기화해야 하며, 엉뚱한 필드를 초기화해도 런
중첩 클래스는 '다른 클래스 안에 정의된 클래스'를 말한다.자신을 감싼 바깥 클래스에서만 사용되어야 하며, 그 외의 쓰임새가 있다면 톱레벨 클래스로 만들어야 한다.정적 멤버 클래스비정적 멤버 클래스익명 클래스지역 클래스첫 번째를 제외한 나머지(비정적 멤버 클래스, 익명
소스 파일 하나에 여러 개의 톱레벨 클래스를 선언하더라도 자바 컴파일러는 불평하지 않는다.하지만 아무런 득이 없을 뿐더러 심각한 위험을 감수해야 한다.한 클래스를 여러 가지로 정의할 수 있으며, 그 중 어느 것을 사용할지는 어느 소스 파일을 먼저 컴파일하느냐에 따라 달
클래스와 인터페이스 선언에 타입 매개변수가 쓰이면 제네릭 클래스 혹은 제네릭 인터페이스라고 하며, 두 가지를 통틀어 제네릭 타입(generic type)이라고 한다.로 타입(raw type)이란 타입 매개변수가 없는 제네릭 타입을 말한다. 예를 들어, List<E
모두 제거한다면 그 코드는 타입 안전성이 보장된다. 즉, 런타임에 ClassCastException이 발생할 일이 없다.안전하다고 검증된 비검사 경고를 숨기지 않고 그대로 두면, 진짜 문제를 알리는 새로운 경고가 나와도 눈치채지 못할 수 있다. 단, 경고를 무시해도 안
1\. 배열은 공변(covariant)인 반면, 제네릭은 불공변(invariant)이다.Sub가 Super의 하위 타입이라면 배열 Sub\[]는 배열 Super\[]의 하위 타입이 되지만, List<Sub>은 List<Super>의 하위 타입도 아니고 상위
아이템7에서 다룬 스택 코드는 원래 제네릭 타입이어야 마땅하다.다음과 같이 타입 매개변수 E를 추가하고, Object를 적절한 타입 매개변수로 바꾸어준다.위의 코드는 new E\[DEFAULT_INITIAL_CAPACITY] 부분에서 오류가 발생한다.이를 해결하기 위한
클래스와 마찬가지로 메서드도 제네릭으로 만들 수 있다.두 집합의 합집합을 반환하는 메서드를 예시로 보자.위의 코드는 컴파일은 되지만 경고가 두 개 발생한다. 경고를 없애기 위해서는, 메서드를 타입 안전하게 만들어야 한다.세 집합(입력 2개, 반환 1개)의 원소 타입을
아이템 28에서 이야기했듯 매개변수화 타입은 불공변(invariant)이다. 즉 서로 다른 타입 Type1과 Type2가 있을 때 List<Type1>은 List<Type2>의 하위 타입도 상위 타입도 아니다.하지만 때론 불공변 방식보다 유연한 무언가가 필요
가변인수(varargs, variable arguments) 메서드와 제네릭은 자바 5 때 함께 추가되었으니 서로 잘 어우러지리라 기대하겠지만, 그렇지 않다.가변인수 메서드를 호출하면 가변인수를 담기 위한 배열이 자동으로 하나 만들어지며, 이 배열은 클라이언트에게 노출
제네릭은 컬렉션과 단일원소 컨테이너에 흔히 쓰인다. 이때 매개변수화되는 대상은 원소가 아닌 컨테이너 자신이다. 따라서 하나의 컨테이너에서 매개변수화할 수 있는 타입의 수가 제한된다.하지만 더 유연한 수단이 필요할 때도 종종 있다.예를 들어, 데이터베이스의 행은 임의 개
자바에서 열거 타입을 지원하기 전에는 정수 열거 패턴(int enum pattern)을 사용하곤 했다.정수 열거 패턴에는 단점이 많다.타입 안전을 보장할 수 없다.표현력이 좋지 않다. 정수 열거 패턴을 위한 별도 이름공간(namespace)를 지원하지 않는다.즉, 이름
대부분의 열거 타입 상수는 하나의 정숫값에 대응된다.그리고 모든 열거 타입은 해당 상수가 그 열거 타입에서 몇 번째 위치인지를 반환하는 메서드를 제공하는데, 이 메서드가 ordinal 메서드다.언뜻 보면 굉장히 편리한 메서드처럼 보이고, 이 메서드를 이용하고 싶은 유혹
✔️ 비트 필드 열거한 값들이 집합으로 사용될 경우, 예전에는 각 상수에 서로 다른 2의 거듭제곱 값을 할당한 정수 열거 패턴을 사용했다. 비트 필드(bit field)란, 이러한 상수들에 비트별 OR 연산을 하여 만들어진 집합을 말한다. > #### 💡 비트
1. EnumMap - 데이터와 열거 타입 매핑 이따금씩 배열이나 리스트에서 원소를 꺼낼 때 ordinal 메서드로 인덱스를 얻는 코드가 있다. Plant 예제를 보자. 식물은 생애주기(LifeCycle)을 가지며, ANNUAL(한해살이), PERENNIAL(여러해살이
열거 타입은 확장할 수 없다.다시 말해, 열거한 값들을 그대로 가져온 다음 값을 더 추가할 수 없다.열거 타입이 확장 불가능하도록 설계한 이유는 다음과 같다.확장한 타입의 원소는 기반 타입의 원소로 취급하지만 그 반대는 성립하지 않는 것은 이상하다.기반 타입과 확장된
전통적으로 도구나 프레임워크를 특별히 다뤄야 할 프로그램 요소에는 딱 구분되는 명명 패턴을 적용해왔다.예를 들어, JUnit은 버전 3까지 테스트 메서드 이름을 test로 시작하도록 했다.오타가 나면 안 된다.예를 들어, 실수로 이름을 tsetSafetyOverride
@Override는 상위 타입의 메서드를 재정의했음을 뜻하는 애너테이션으로, 메서드 선언에만 달 수 있다.이 애너테이션을 일관되게 사용하면 여러가지 악명 높은 버그를 예방할 수 있다.위의 예제는 equals를 재정의할 의도였지만, 재정의(overriding)이 아닌 다
마커 인터페이스란, "아무 메서드도 담고 있지 않고, 단지 자신을 구현하는 클래스가 특정 속성을 가짐을 표시해주는 인터페이스"이다.마커 인터페이스의 예시로는, Serializable 인터페이스가 있다.Serializable은 자신을 구현한 클래스의 인스턴스는 Objec
JDK 1.1 이전 예전에는 자바에서 함수 타입을 표현할 때 추상 메서드를 하나만 담은 인터페이스 (드물게는 추상 클래스)를 사용하였다. 이런 인터페이스의 인스턴스를 함수 객체(function object)라고 한다. JDK 1.1 JDK 1.1이 등장하면서 함수 객
람다는 익명 클래스보다 간결하다는 특징이 있다.그런데 자바에는 람다보다 함수 객체를 더 간결하게 만드는 방법이 있는데, 그게 바로 메서드 참조(method reference) 다.multiset을 구현하는 예제를 통해 람다와 메서드 참조를 비교해보자. 람다 이용 key
자바가 람다를 지원하면서 상위 클래스의 기본 메서드를 재정의하는 템플릿 메서드 패턴의 매력이 크게 줄었다. > 이를 대체하는 현대적인 해법은 함수 객체를 받는 정적 팩터리나 생성자를 제공하는 것이다. > 이 말은, 함수 객체를 매개변수로 받는 생성자와 메서드를 더 많이
스트림 API는 다량의 데이터 처리 작업(순차적/병렬적 모두)을 돕고자 자바 8에서 추가되었다.이 API가 제공하는 추상 개념의 핵심은 다음의 2가지다.스트림 (stream) : 데이터 원소의 유한 혹은 무한 시퀀스(sequence)스트림 파이프라인 (stream pi
스트림 패러다임의 핵심은 계산을 일련의 변환(transformation)으로 재구성하는 부분이다.각 변환 단계는 순수 함수 여야 한다. 즉, 다른 가변 상태를 참조하지 않고, 함수 스스로도 다른 상태를 변경하지 않는다.\+) 순수 함수란, 오직 입력만이 결과에 영향을
1. 원소 시퀀스 반환 타입 컬랙션 인터페이스 (Collection, Set, List) Iterable 인터페이스 배열 스트림 (자바 8부터 지원) 자바 7까지의 원소 시퀀스 반환 타입의 선택 기본적으로 컬렉션 인터페이스를 사용 for-each문에서만 사용하거
자바 8부터는 parallel 메서드만 한 번 호출하면 파이프라인을 병렬 실행할 수 있는 스트림을 지원한다.그러나 스트림을 올바로 병렬화하는 것은 매우 어려운 작업이다.스트림을 잘못 병렬화하면 (응답 불가를 포함해) 성능이 나빠질 뿐만 아니라 결과 자체가 잘못되거나 예
메서드와 생성자에서 입력 매개변수의 값에 대한 제약은 반드시 문서화해야 하며, 메서드 몸체가 시작되기 전에 검사해야 한다.이는 "오류는 가능한 한 빨리 (발생한 곳에서) 잡아야 한다"는 일반 원칙의 한 사례이기도 하다.특히, 생성자 매개변수의 유효성 검사는 클래스 불변
자바는 안전한 언어이지만 다른 클래스로부터의 침범을 아무런 노력 없이 다 막을 수 있는 것은 아니다. 따라서 클라이언트가 불변식을 깨뜨리려고 혈안되어 있다고 가정하고 방어적으로 프로그래밍해야 한다.위와 같이 코드를 작성할 경우, 인스턴스 내부를 향한 공격에 노출될 수
이번 아이템에서는 개별 아이템으로 두기 애매한 API 설계 요령들을 모아 설명한다.항상 표준 명명 규칙을 따라야 한다.같은 패키지에 속한 다른 이름들과 일관디게 짓고, 개발자 커뮤니티에서 널리 받아들여지는 이름을 하자.애매하면 자바 라이브러리의 API 가이드를 참조하라
재정의(overriding)한 메서드는 동적으로 선택되지만, 다중정의(overloading)한 메서드는 정적으로 선택된다.즉, 다중정의된 메서드 사이에서는 객체의 런타임 타입은 전혀 중요하지 않다. 선택은 매개변수의 컴파일타임 타입에 의해 이뤄진다.API 사용자가 매개
가변인수 메서드는 명시한 타입의 인수를 0개 이상 받을 수 있다.가장 먼저 인수 개수와 길이 같은 배열을 만든다. 인수들을 생성한 배열에 저장하여 가변인수 메서드에 건네준다.다음은 int 인수들의 합을 계산하는 가변인수 메서드다.인수가 1개 이상이어야 할 때는 첫 번째
null을 반환하는 예시 > #### 🔖 핵심 정리 > null이 아닌, 빈 배열이나 컬렉션을 반환하라. > null을 반환하는 API는 사용하기 어렵고 오류 처리 코드도 늘어난다. > 그렇다고 성능이 좋은 것도 아니다.
메서드가 특정 조건에서 값을 반환할 수 없을 때 취할 수 있는 선택지는 3가지다.예외 를 던진다.null 을 반환한다.Optional<T> 를 사용한다.자바 8 이전에는 1,2만 지원했다.1번 예외는 정말 예외적인 상황에서만 사용해야 하며, 예외를 생성할 때 스택
API 문서를 사람이 직접 작성하면 코드가 변경될 때마다 매번 함께 수정해줘야 하는데, 자바독(Javadoc) 유틸리티는 이 귀찮은 작업을 도와준다.자바독은 소스코드 파일에서 문서화 주석(doc comment; 자바독 주석)이라는 특수한 형태로 기술된 설명을 추려 AP
지역변수의 유효 범위를 최소로 줄이면 코드 가독성과 유지보수성이 높아지고 오류 가능성이 낮아진다.지역변수의 범위를 최소화할 수 있는 방법을 알아보자.지역변수의 범위를 줄이는 가장 강력한 기법이다.사용하려면 멀었는데, 미리 선언부터 해두면 코드가 어수선해져 가독성이 떨어
전통적인 for 문은 while 문보다는 낫지만 가장 좋은 방법은 아니다.반복자와 인덱스 변수는 코드를 지저분하게 한다.사용되는 요소의 종류가 늘어나 오류 가능성이 높아진다.컬렉션과 배열의 코드 형태가 상당히 달라진다.컬렉션의 중첩 반복 시, 일반적인 반복문을 사용하면
표준 라이브러리를 사용하면 그 코드를 작성한 전문가의 지식과 여러분보다 앞서 사용한 다른 프로그래머들의 경험을 활용할 수 있다.핵심적인 일과 크게 관련 없는 문제를 해결하느라 시간을 허비하지 않아도 된다.따로 노력하지 않아도 성능이 지속해서 개선된다.기능이 점점 많아진
float 와 double float와 double 타입은 넓은 범위의 수를 빠르게 정밀한 '근사치'로 계산하도록 설계되었기 때문에, 정확한 결과가 필요할 때는 사용하면 안 된다. 특히 금융 관련 계산과는 맞지 않는다. 0.1 혹은 10의 음의 거듭제곱 수를 표현할
자바의 데이터 타입은 크게 기본 타입(int, double, boolean, ...)과 참조 타입(String, List, ...) 으로 나눌 수 있다.각각의 기본 타입에는 대응하는 참조 타입이 하나씩 있으며, 이를 박싱된 기본 타입 이라고 한다.int - Intege
문자열은 다른 값 타입을 대신하기에 적합하지 않다.수치형이라면, int, float, BigInteger 등 적당한 수치 타입을 사용하자.'예/아니오' 질문의 답이라면, 적절한 열거 타입이나 boolean 타입을 사용하자.여러 요소가 혼합된 데이터(혼합 타입)인 경우,
문자열 연결 연산자(+)는 여러 문자열을 하나로 합쳐주는 편리한 수단이다.그러나 한 줄짜리 출력값 혹은 작고 크기가 고정된 객체의 문자열 포현을 만들 때라면 괜찮지만, 본격적으로 사용하기 시작하면 성능 저하를 감내하기 어렵다.문자열 연결 연산자로 문자열 n개를 잇는 시
적합한 인터페이스만 있다면 매개변수뿐 아니라 반환값, 변수, 필드를 전부 인터페이스 타입으로 선언하라. 객체의 실제 클래스를 사용해야 할 상황은 '오직' 생성자로 생성할 때뿐이다. 인터페이스 사용 장점 인터페이스를 타입으로 사용하는 습관을 길러두면 프로그램이 훨
리플렉션 기능(java.lang.reflect)을 이용하면 프로그램에서 임의의 클래스에 접근할 수 있다.Class 객체가 주어지면 그 클래스의 생성자, 메서드, 필드에 해당하는 Constructor, Method, Field 인스턴스를 가져올 수 있다. 또한 이 인스턴
자바 네이티브 인터페이스(Java Native Interface, JNI)는 자바 프로그램이 네이티브 메서드 를 호출하는 기술을 말한다.네이티브 메서드 란 C나 C++ 같은 네이티브 프로그래밍 언어로 작성한 메서드를 말한다.네이티브 메서드는 주로 다음과 같은 용도로 사
최적화 이야기를 하기에 앞서, 다음의 격언들을 보자.(맹목적인 어리석음을 포장해) 그 어떤 핑계보다 효율성이라는 이름 아래 행해진 컴퓨팅 죄악이 더 많다(심지어 효율을 높이지도 못하면서) \- 윌리엄 울프Wulf72(전체의 97% 정도인) 자그마한 효율성은 모두 잊자.
자바 플랫폼은 명명 규칙이 잘 정립되어 있으며, 그중 많은 것이 자바 언어 명세JLS, 6.1에 기술되어 있다. 자바의 명명 규칙은 크게 철자 규칙과 문법 규칙, 두 범주로 나뉜다.철자 규칙은 패키지, 클래스, 인터페이스, 메서드, 필드, 타입 변수의 이름을 다룬다.패
예외는 오직 예외 상황에서만 써야 한다. 절대로 일상적인 제어 흐름용으로 쓰여서는 안 된다. 표준적이고 쉽게 이해되는 관용구를 사용하고, 성능 개선을 목적으로 과하게 머리를 쓴 기법은 자제하자. 실제로 성능이 좋아지더라도 자바 플랫폼이 꾸준히 개선되고 있는 최적화로
자바는 문제 상황을 알리는 타입(throwable)으로 검사 예외, 런타임 예외, 에러, 이렇게 세 가지를 제공한다.언제 어떤 것을 사용해야 할까?호출하는 쪽에서 복구할 것으로 여겨지는 상황이라면 검사 예외를 사용하자. 이것은 검사와 비검사 예외를 구분하는 기본 규칙이
검사 예외는 제대로 활용하면 API와 프로그램의 질을 높일 수 있다. 검사 예외는 발생한 문제를 프로그래머가 처리하여 안전성을 높이게끔 해준다.그러나 검사 예외를 과하게 사용하면 오히려 쓰기 불편한 API가 된다. 어떤 메서드가 검사 예외를 던질 수 있다고 선언됐다면,
자바 라이브러리는 대부분 API에서 쓰기에 충분한 수의 예외를 제공한다.표준 예외를 재사용하면 얻는 점이 많다. 다른 사람이 익히고 사용하기 쉬워진다는 것이다. 많은 프로그래머에게 이미 익숙해진 규약을 그대로 따르기 때문이다. 낯선 예외를 사용하지 않으므로 읽기 쉽다.
메서드가 저수준 예외를 처리하지 않고 바깥으로 전파해버리면, 종종 수행하려는 일과 관련 없어 보이는 예외가 발생한다. 이는 내부 구현 방식을 드러내어 윗 레벨 API를 오염시킨다. 다음 릴리스에서 구현 방식을 바꾸면 다른 예외가 튀어나와 기존 클라이언트 프로그램을 깨지
메서드가 던지는 예외는 그 메서드를 올바로 사용하는 데 아주 중요한 정보이므로, 각 메서드가 던지는 예외 하나하나를 문서화하는 데 충분한 시간을 쏟아야 한다.검사 예외는 항상 따로따로 선언하고, 각 예외가 발생하는 상황을 자바독의 @throw 태그를 사용하여 정확히 문
예외를 잡지 못해 프로그램이 실패하면 자바 시스템은 그 예외의 스택 추적(stack trace) 정보를 자동으로 출력한다. 스택 추적은 예외 객체의 toString 메서드를 호출해 얻은 문자열이다. 이는 보통 예외 클래스 이름 뒤에 상세 메시지가 붙는 형태다. 이 정보
실패 원자적(failure-atomic) 이란, 호출된 메서드가 실패하더라도 해당 객체는 메서드 호출 전 상태를 유지하는 것을 말한다. 1\. 불변 객체로 설계하기불변 객체는 태생적으로 실패 원자적이다. 불변 객체의 상태는 생성 시점에 고정되어 변하지 않기 때문에, 메
API 설계자가 메서드 선언에 예외를 명시하는 까닭은, 그 메서드를 사용할 때 적절한 조치를 취해달라고 말하는 것이다. API 설계자의 목소리를 흘려버리지 말자. 물론 예외를 무시해야 할 때도 있다. 예를 들어 FileInputStream 을 닫을 때가 그렇다. 파일
synchronized synchronized 키워드는 해당 메서드나 블록을 한번에 한 스레드씩 수행하도록 보장한다. 많은 프로그래머가 동기화를 배타적 실행 용도로만 생각한다. 배타적 실행이란, 한 스레드가 변경하는 중이라서 상태가 일관되지 않은 순간의 객체를 다른 스레드가 보지 못하게 막는 것을 의미한다. 그러나 동기화에는 중요한 기능이 하나 더 있다...
과도한 동기화는 성능을 떨어뜨리고, 교착상태에 빠뜨리고, 심지어 예측할 수 없는 동작을 낳기도 한다.응답 불가와 완전 실패를 피하려면 동기화 메서드나 동기화 블록 안에서는 제어를 절대로 클라이언트에 양도하면 안 된다.동기화된 영역 안에서는 재정의할 수 있는 메서드는 호
java.util.concurrent 패키지는 실행자 프레임워크(Executor Framework)라고 하는 인터페이스 기반의 유연한 태스크 실행 기능을 담고 있다. 이것을 이용하면, 다음의 아주 짧은 코드로 작업 큐를 사용할 수 있다.실행자 서비스의 주요 기능은 다음