개발서적/Effective Java

    [Effective Java] 추상화 수준에 맞는 예외를 던지라

    추상화 수준에 맞는 예외를 던지라 수행하려는 일과 관련 없어 보이는 예외가 튀어나오면 당황스럽다. 메서드가 저수준 예외를 처리하지 않고 바깥으로 전파해버릴 때 이런 경우가 종종 발생한다. 이러한 예외는 내부 구현 방식을 드러내어 윗 레벨 API를 오염시키기까지 한다. 예외 번역 이러한 문제를 피하기 위해 상위 계층에서는 저수준 예외를 잡아 자신의 추상화 수준에 맞는 예외로 바꿔 던져야 한다. 이를 '예외 번역' 이라고 한다. 다음은 AbstractSequentialList에서 수행하는 예외 번역의 예다. public E get(int index) { ListIterator i = listIterator(index); try { return i.next(); } catch (NoSuchElementExce..

    [Effective Java] 표준 예외를 사용하라

    표준 예외를 사용해야 하는 이유 내가 작성한 코드가 다른 사람이 익히고 사용하기 쉬운 코드가 된다. 예외 클래스 수가 적을수록 메모리 사용량도 줄고 클래스를 적재하는 시간도 적게 걸린다. 자주 사용되는 표준 예외 IllegalArgumentException 호출자가 인수로 부적절한 값을 넘길 때 사용한다. e.g ) 반복 횟수를 지정하는 매개변수에 음수를 건내는 경우 IllegalStateException 대상 객체의 상태가 호출된 메서드를 수행하기에 적합하지 않을 때 사용한다. e.g ) 제대로 초기화되지 않은 객체를 사용하려고 하는 경우 메서드가 던지는 모든 예외를 잘못된 인수나 상태라고 뭉뚱그릴 수도 있겠지만, 특수한 경우에는 더 구체적인 예외를 사용하는 것이 좋다. NullPointExceptio..

    [Effective Java] 필요 없는 검사 예외 사용은 피하라

    검사 예외의 장단점 장점 검사 예외는 발생한 문제를 프로그래머가 처리하여 안정성을 높일 수 있게 도와준다. 단점 검사 예외를 사용하면 API 사용자는 catch 블록을 두어 예외를 처리하는 코드를 작성해야 하기 때문에 오히려 쓰기 불편한 API가 된다. 검사 예외를 던지는 메서드는 스트림 안에서 직접 사용할 수 없다. 비검사 예외를 사용하자 API를 제대로 사용해도 발생할 수 있는 예외이거나, 프로그래머가 의미 있는 조치를 취할 수 있는 경우가 아니라면 비검사 예외를 사용하자. 특히 메서드가 단 하나의 검사 예외만 던질 때는 예외 하나 때문에 try-catch문을 사용해야 하므로 더욱 더 신경쓰자. 검사 예외를 회피하는 방법 적절한 결과 타입을 담은 옵셔널을 반환한다. 검사 예외 대신 단순히 빈 옵셔널을..

    [Effective Java] 복구할 수 있는 상황에는 검사 예외를, 프로그래밍 오류에는 런타임 예외를 사용하라

    [Effective Java] 복구할 수 있는 상황에는 검사 예외를, 프로그래밍 오류에는 런타임 예외를 사용하라

    자바는 문제 상황을 알리는 타입으로 세 가지를 제공한다. 자바 예외 클래스의 계층구조 이 챕터를 공부하기 전에 자바 예외 클래스의 계층 구조를 보고 간단하게 살펴보자. 예외는 복구 유무에 따라 크게 두 가지로 구분할 수 있다. Error 클래스 Error 클래스는 메모리 부족이나 스택오버플로우와 같이 일단 발생하면 복구할 수 없는 심각한 오류이다. 에러가 발생하면 프로그래머가 할 수 있는 일은 없다. Exception 클래스 예외는 발생하더라도 프로그래머가 이에 대한 적절한 조취를 미리 취해놓을 수 있다. 에러 발생지에 따라 두 가지로 구분될 수 있다. RuntimeException : 프로그래머들의 실수에 의해 발생할 수 있는 예외가 주로 발생한다. 컴파일러가 인지 못하고, 실행 중에 발생한 문제로 '..

    [Effective Java] 예외는 진짜 예외 상황에만 사용하라

    예외의 잘못된 사용 다음은 예외를 잘못 사용한 예시이다. try { int i = 0; while(true) range[i++].climb(); }catch (ArrayIndexOutOfBoundException e) { } 이 코드의 문제는 다음과 같다. 전혀 객관적이지 않다. 다음과 같이 작성하면 모든 사람이 직관적으로 이해할 수 있다. for (Mountain m : range) m.climb(); 제대로 동작하지 않을 수 있다. 반복문안에 잘못된 코드가 숨어져 있다면 흐름 제어에 쓰인 예외가 이 버그를 숨겨 디버깅을 더 어렵게 만든다. 예외는 필요할 때만 사용하자 예외는 오직 예외 상황에서만 사용해야 한다. 절대로 일상적인 제어 흐름용으로 쓰여서는 안 된다. 이 원칙은 API 설계에도 적용된다. ..