맞는데 왜 틀릴까..?

Java/Effective Java 77

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

메서드가 저수준 예외를 처리하지 않고 바깥으로 전파해 버리면 수행하려는 일과 관련 없어 보이는 예외가 튀어나올 수 있다. 이는 내부 구현 방식을 드러내어 윗 레벨 API를 오염시킨다. 다음 릴리스에서 구현 방식을 바꾸면 다른 예외가 튀어나와 기존 클라이언트 프로그램을 깨지게 할 수도 있다. 저수준 예외 저수준 예외는 주로 하위 레벨의 컴포넌트나 라이브러리에서 발생하는 예외를 의미한다. 이 예외들은 주로 프로그램의 내부 동작, 하위 레벨의 리소스 접근, 네트워크 통신 등과 관련이 있다. 프로그램의 외부 요인으로 발생하거나, 하위 레벨에서 발생한 문제로 인해 발생하는 경우가 많아 애플리케이션 개발자가 직접 제어하기 어려울 수 있다. 파일을 열다가 발생한 입출력 예외 네트워크 연결 중에 발생한 소켓 예외 프로..

Java/Effective Java 2023.08.11

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

자바 라이브러리는 대부분 API에서 쓰기에 충분한 수의 예외를 제공한다. 표준 예외를 재사용하면 얻는 게 많다. 많은 프로그래머에게 이미 익숙해진 규약을 따르기 때문에 내가 만든 API를 다른 사람이 익히고 사용하기 쉬워진다. 예외 클래스 수가 적을수록 메모리 사용량도 줄고 클래스를 적재하는 시간도 적게 걸린다. 표준 예외 IllegalArgumentException 호출자가 인수로 부적절한 값을 넘길 때 던지는 예외 ex) 반복 횟수를 지정하는 매개변수에 음수를 건넬 때 IllegalStateException 대상 객체의 상태가 호출된 메서드를 수행하기에 적합하지 않을 때 던지는 예외 ex) 제대로 초기화되지 않은 객체를 사용하려 할 때 NullPointerException null 값을 허용하지 않는..

Java/Effective Java 2023.08.06

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

검사 예외를 제대로 활용하면 API와 프로그램의 질을 높일 수 있다. 결과를 코드로 반환하거나 비검사 예외를 던지는 것과 달리, 검사 예외는 발생한 문제를 프로그래머가 처리하여 안전성을 높이게끔 해준다. 검사 예외의 과한 사용 검사 예외를 과하게 사용하면 오히려 쓰기 불편한 API가 된다. 어떤 메서드가 검사 예외를 던질 수 있다고 선언됐다면, 이를 호출하는 코드에서는 catch 블록을 두어 그 예외를 붙잡아 처리하거나 더 바깥으로 던져 문제를 전파해야만 한다. 검사 예외를 던지는 메서드는 스트림 안에서 직접 사용할 수 없다. API를 제대로 사용해도 발생할 수 있는 예외이거나, 프로그래머가 의미 있는 조치를 취할 수 있는 경우에 검사 예외를 사용하고, 둘 다 아니면 비검사 예외를 사용하자 아래와 같은 ..

Java/Effective Java 2023.08.06

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

자바는 문제 상황을 알리는 타입(throwable)으로 검사 예외, 런타임 예외, 에러를 제공한다. 언제 무엇을 사용할지 헷갈리는 프로그래머들이 많기 때문에 참조할 좋은 지침들이 있다. 1. 검사 예외 (Checked Exception) Exception 클래스를 상속받은 예외 타입 중에서 RuntimeException을 제외한 나머지 예외들 컴파일러가 검사 예외를 체크하고, 예외를 처리하지 않으면 컴파일 오류가 발생한다. I/O 문제, 네트워크 연결 실패 등 프로그램의 외부적인 환경 변화에 따른 문제 상황을 나타내는 데 사용된다. 2. 런타임 예외 (Runtime Exception) RuntimeException 클래스를 상속받은 예외 타입을 가리킨다. 컴파일러가 이 예외를 체크하지 않으며, 예외 처리..

Java/Effective Java 2023.08.05

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

예외는 오직 예외 상황에서만 써야 한다. 절대로 일상적인 제어 흐름용으로 쓰여선 안된다. 부적절한 예 - 예외를 사용한 최적화 배열의 원소를 순회하는 표준적인 관용구 for (Mountain m : range) m.climb(); 완전히 잘못 사용한 예외를 활용한 최적화 try{ int i =0; while(true) range[i++].climb(); } catch (ArrayIndexOutOfBoundsException e){ } 최적화를 위한 잘못된 추론 JVM은 배열에 접근할 때마다 경계를 넘지 않는지 검사한다. 일반적인 반복문도 배열 경계에 도달하면 종료한다. 따라서 경계를 넘는지 검사하는 일이 중복되므로 생략해 버리자. 추론이 잘못된 점 예외는 예외 상황에 쓸 용도로 설계되었으므로 명확한 검사..

Java/Effective Java 2023.08.05

[Effective Java] Item 68. 일반적으로 통용되는 명명 규칙을 따르라

자바의 명명 규칙은 크게 철자와 문법 두 범주로 나뉜다. 철자 규칙 : 패키지, 클래스, 인터페이스, 메서드, 필드, 타입 변수 철자 규칙이나 문법 규칙을 어기면 다른 프로그래머들이 그 코드를 읽기 번거로울 뿐 아니라 다른 뜻으로 오해할 수도 있다. 철자 규칙 철자 규칙은 특별한 이유가 없는 한 반드시 따라야 한다. 이 규칙을 어긴 API는 사용하기 어렵고, 유지보수하기 어렵다. 패키지 패키지와 모듈 이름은 각 요소를 점(.)으로 구분하여 계층적으로 짓는다. 요소들은 모두 소문자 알파벳 혹은 드물게 숫자로 이루어진다. 각 요소는 일반적으로 8 자 이하의 짧은 단어로, 그 단어의 약어 또는 첫 글자만 따서 지어도 좋다. 인터넷 도메인 이름을 역순으로 사용한다. 예외적으로 표준 라이브러리와 선택적 패키지들은..

Java/Effective Java 2023.08.04

[Effective Java] Item 67. 최적화는 신중히 하라

이 책에서 모든 사람이 마음 깊이 새겨야 할 최적화 격언 3개를 소개해주었다. 그 어떤 핑계보다 효율성이라는 이름 아래 행해진 컴퓨팅 죄악이 더 많다 - 윌리엄 울프 전체의 97% 정도인 자그마한 효율성은 모두 잊자. 섣부른 최적화가 만악의 근원이다. - 도널드 크누스 최적화를 할 때는 다음 두 규칙을 따르라. 1. 하지 마라 2. (전문가 한정) 아직 하지 마라. 다시 말해, 완전히 명백하고 최적화되지 않은 해법을 찾을 때까지는 하지 마라 - M.A. 잭슨 이 격언들은 자바가 탄생하기 20년 전에 나온 것으로, 최적화는 좋은 결과보다는 해로운 결과로 이어지기 쉽고, 섣불리 진행하면 특히 더 그렇다는 것을 알려준다. 성능 때문에 견고한 구조를 희생하지 말자. 빠른 프로그램보다는 좋은 프로그램을 작성하자...

Java/Effective Java 2023.08.03

[Effective Java] Item 66. 네이티브 메서드는 신중히 사용하라

네이티브 메서드 C, C++ 같은 네이티브 프로그래밍 언어로 작성한 메서드다. 자바 네이티브 인터페이스는 자바 프로그램이 네이티브 메서드를 호출하는 기술이다. 네이티브 메서드의 주요 쓰임 1. 레지스트리 같은 플랫폼 특화 기능을 사용한다. 2. 네이티브 코드로 작성된 기존 라이브러리를 사용한다. ex) 레거시 테이터를 사용하는 레거시 라이브러리 ( 더 이상 쓰기 힘들고 정상적이지 않는 화나게 만드는 난해한 코드) 3. 성능 개선을 목적으로 성능에 결정적인 영향을 주는 영역만 따로 네이티브 언어로 작성한다. 성능을 개선할 목적으로 네이티브 메서드를 사용하는 것은 권장하지 않는다. 자바 초기 시절이라면 이야기가 다르지만, JVM은 그동안 엄청난 속도로 발전해 왔기 때문에 대부분에 작업에서 지금의 자바는 다른..

Java/Effective Java 2023.07.30

[Effective Java] Item 65. 리플렉션보다는 인터페이스를 사용하라

리플렉션(Reflection) 프로그램 실행 중에 클래스의 정보를 동적으로 가져오고, 해당 클래스의 인스턴스를 생성하거나 메서드를 호출하는 기능을 말한다. 즉, 리플렉션을 통해 실행 중인 자바 프로그램이 자신의 구조를 분석하고 수정할 수 있는 능력을 갖게 된다. 1. 리플렉션 기능을 이용하면 프로그램에서 임의의 클래스에 접근할 수 있다. Class 객체가 주어지면 그 클래스의 생성자, 메서드, 필드에 해당하는 Constructor, Method, Field 인스턴스를 가져올 수 있고, 이어서 이 인스턴스들로는 그 클래스의 멤버 이름, 필드 타입, 메서드 시그니처들을 가져올 수 있다. Constructor, Method, Field 인스턴스를 이용해 각각에 연결된 실제 클래스의 인스턴스를 생성하거나, 메서..

Java/Effective Java 2023.07.30

[Effective Java] Item 64. 객체는 인터페이스를 사용해 참조하라

객체의 실제 클래스를 사용해야 할 상황은 오직 생성자로 생성할 때뿐이다. 적합한 인터페이스만 있다면 매개변수뿐 아니라 반환값, 변수, 필드를 전부 인터페이스 타입으로 선언하라. Set 인터페이스를 구현한 LinkedHashSet 변수를 선언 // 좋은 예 : 인터페이스를 타입으로 사용했다. Set sonSet = new LinkedHashSet(); // 나쁜 예 : 클래스를 타입으로 사용했다. LinkedHashSet sonSet = new LinkedHashSet(); 인터페이스를 타입으로 사용하는 습관을 길러두면 프로그램이 훨씬 유연해진다. 나중에 구현 클래스를 교체하고자 한다면 그저 새 클래스의 생성자를 호출해주기만 하면 된다. 다른 코드는 전혀 손대지 않고 새로 구현한 클래스로의 교체를 완료할 ..

Java/Effective Java 2023.07.30