EffectiveJava
-
[Effective Java] wait와 notify보다는 동시성 유틸리티를 애용하라Java 2023. 2. 14. 02:44
wait와 notify보다는 동시성 유틸리티를 애용하라 자바 5에서 도입된 고수준의 동시성 유틸리티가 이전이라면 wait와 notify로 하드코딩해야 했던 전형적인 일들을 대신 처리해주기 때문에 지금은 wait과 notify를 사용해야 할 이유가 많이 줄었다. 갖고 있던 고유 락을 해제하고, 스레드를 잠들게 하는 wait와 잠들어 있던 스레드 중 임의로 하나를 골라 깨우는 notify는 synchronized 블록이나 메소드에서 호출되어야하고, 올바르게 사용하기가 아주 까다로우니 고수준 동시성 유틸리티를 사용하자. java.util.concurrent의 고수준 유틸리티는 세 범주로 나눌 수 있다. 실행자 프레임워크, 동시성 컬렉션, 동기화 장치다. 동시성 컬렉션 동시성 컬렉션은 List, Queue, M..
-
[Effective Java] 필요 없는 검사 예외 사용은 피하라Java 2023. 2. 6. 12:47
필요 없는 검사 예외 사용은 피하라 검사 예외를 싫어하는 자바 프로그래머가 많지만 제대로 활용하면 API와 프로그램의 질을 높일 수 있다. 결과를 코드로 반환하거나 비검사 예외를 던지는 것과 달리, 검사 예외는 발생한 문제를 프로그래머가 처리하여 안정성을 높이게끔 해준다. 물론, 검사 예외를 과하게 사용하면 오히려 쓰기 불편한 API가 된다. 어떤 메서드가 검사 예외를 던질 수 있다고 선언됐다면, 이를 호출하는 코드에서는 catch 블록을 두어 그 예외를 붙잡아 처리하거나 더 바깥으로 던져 문제를 전파해야 한다. 검사 예외 회피 방법 - 1. 비검사 예외 API를 제대로 사용해도 발생할 수 있는 예외이거나, 프로그래머가 의미 있는 조치를 취할 수 있는 경우라면 이 정도 부담쯤은 받아들일 수 있을 것이다...
-
[Effective Java] 복구할 수 있는 상황에는 검사 예외를, 프로그래밍 오류에는 런타임 예외를 사용하라Java 2023. 2. 6. 12:46
복구할 수 있는 상황에는 검사 예외를, 프로그래밍 오류에는 런타임 예외를 사용하라 자바는 문제 상황을 알리는 타입(throwable)으로 검사 예외, 런타임 예외, 에러, 이렇게 세 가지를 제공한다. 검사 예외 개발자가 명시해야 하는 부분은 검사 예외인 Exception으로 어플리케이션 수행 중 일어날 법한 예외를 검사하고 대비하라는 목적으로 사용된다. 컴파일 단계에서 컴파일러가 체크한다. 이를 처리하지 않으면 컴파일 에러가 발생한다. 과도한 예외 검출은 시스템의 성능을 저하시킬 수 있다. 비검사 예외 Error는 시스템적인 예외를 의미한다. 개발자가 예외를 try-catch 로 잡지 않았을 때 발생한다. 런타임에 컴파일러에게 예외가 걸리지지 않았을 경우 발생한다. 즉, 코드 상의 문제이다. 대표적으로 ..
-
[Effective Java] 예외는 진짜 예외 상황에만 사용하라Java 2023. 2. 6. 12:45
예외 예외를 제대로 활용한다면 프로그램의 가독성, 신뢰성, 유지보수성이 높아지지만, 잘못 사용하면 반대의 효과만 나타난다. 예외는 진짜 예외 상황에만 사용하라 예외를 사용한 반복문은 코드를 헷갈리게 하고 성능을 떨어뜨린다. // 예외를 완전히 잘못 사용한 예 try{ int i = 0; while(true) range[i++].climb(); } catch (ArrayIndexOutOfBoundsException e){ } 위의 코드는 전혀 직관적이지 않다. 이 코드는 배열의 원소를 순회하는데, 아주 끔찍한 방식으로 하고 있다. 무한루프를 돌다가 배열의 끝에 도달해 ArrayIndexOutOfBoundsException이 발생하면 끝을 내는 것이다. 다음과 같이 표준적인 관용구대로 작성했다면 모든 자바 ..
-
[Effective Java] 다른 타입이 적절하다면 문자열 사용을 피하라Java 2023. 2. 3. 10:30
문자열(String)은 텍스트를 표현하도록 설계되었고, 그 일을 아주 멋지게 해낸다. 근데 문자열은 워낙 흔하고 자바가 잘 지원해주어 원래 의도하지 않은 용도로도 쓰이는 경향이 있다. 문자열을 쓰지 않아야 할 사례 1. 문자열은 다른 값 타입을 대신하기에 적합하지 않다. 많은 사람이 파일, 네트워크, 키보드 입력으로부터 데이터를 받을 때 주로 문자열을 사용한다. 입력받을 데이터가 진짜 문자열일 때만 그렇게 하는게 좋다. 받은 데이터가 수치형이라면 int, float, BigInteger등 적당한 수치 타입으로 변환해야 한다. 예/아니오 질문의 답이라면 적절한 열거 타입이나 boolean으로 변환해야 한다. 기본 타입이든 참조 타입이든 적절한 값 타입이 있다면 그것을 사용하고, 없다면 새로 하나 작성하라...
-
[Effective Java] 박싱된 기본 타입보다는 기본 타입을 사용하라Java 2023. 2. 3. 10:29
자바의 데이터 타입은 크게 두 가지로 나눌 수 있다. int, double, boolean 같은 기본 타입과 String, List 같은 참조 타입이다. 그리고 각각의 기본 타입에는 대응하는 참조 타입이 하나씩 있으며, 이를 박싱된 기본 타입이라고 한다. int, double, boolean에 대응하는 방식된 기본 타입은 Integer, Double, Boolean 이다. 기본 타입과 박싱된 기본 타입 사이에는 분명한 차이가 있으니 어떤 타입을 사용하는지는 상당히 중요하다. 주의해서 선택해야 한다. 기본 타입과 박싱된 기본 타입의 주된 차이 1. 기본 타입은 값만 가지고 있으나, 박싱된 기본 타입은 값에 더해 식별성(identity)이란 속성을 갖는다. 달리 말하면 방식된 기본 타입의 두 인스턴스는 값이..
-
[Effective Java] 정확한 답이 필요하다면 float과 double은 피하라Java 2023. 2. 3. 10:29
float과 double 타입은 과학과 공학 계산용으로 설계되었다. 이진 부동소수점 연산에 쓰이며, 넓은 범위의 수를 빠르게 정밀한 '근사치'로 계산하도록 세심하게 설계되었다. 따라서 정확한 결과가 필요할 때는 사용하면 안된다. float과 double 타입은 특히 금융 관련 계산과는 맞지 않는다. 예 1) 주머니에 1.03달러가 있었는데 그중 42센트를 썼다고 해보면 남은 돈은 얼마인가? System.out.println(1.03 - 0.42); // 출력: 0.6100000000000001 예 2) 주머니에 1달러가 있었는데 10센트짜리 사탕 9개를 샀다고 해보면 얼마가 남았을까? System.out.println(1.00 - 9 * 0.10); // 출력: 0.0999999999999998 예3) ..
-
[Effective Java] 적시에 방어적 복사본을 만들라Java 2023. 2. 3. 10:28
자바는 안전한 언어다. 네이티브 메서드를 사용하지 않으니, C, C++ 같이 안전하지 않은 언어에서 흔히 보는 버퍼 오버런, 배열 오버런, 와일드 포인터 같은 메모리 충돌 오류에서 안전하다. 자바로 작성한 클래스는 시스템의 다른 부분에서 무슨 짓을 하든 그 불변식이 지켜진다. 불변식을 깨드리는 예시 하지만 아무리 자바라 해도 다른 클래스로부터의 침범을 아무런 노력 없이 다 막을 수 있는 건 아니다. 그러니 클라이언트가 여러분의 불변식을 깨뜨리려 혈안이 되어 있다고 가정하고 방어적으로 프로그래밍해야 한다. (평범한 프로그래머도 순전히 실수로 여러분의 클래스를 오작동하게 만들 수 있다.) 어떤 객체든 그 객체의 허락 없이는 외부에서 내부를 수정하는 일은 불가능 하지만, 주의를 기울이지 않으면 자기도 모르게 ..