개발/Effective Java 66

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

[Effective Java] item 71. 필요 없는 검사 예외 사용은 피하라 검사 예외의 장점 검사 예외를 싫어하는 자바 프로그래머가 많지만 제대로 활용하면 API와 프로그램의 질을 높일 수 있다. 결과를 코드로 반환하거나 비검사 예외를 던지는 것과 달리, 검사 예외는 발생한 문제를 프로그래머가 처리하여 안전성을 높이게끔 해준다. 검사 예외의 사용 물론, 검사 예외를 과하게 사용하면 오히려 쓰기 불편한 API가 된다. 어떤 메서드가 검사 예외를 던질 수 있다고 선언됐다면, 이를 호출하는 코드에서는 catch 블록을 두어 그 예외를 붙잡아 처리하거나 더 바깥으로 던져 문제를 전파해야만 한다. 검사 예외를 던지는 메서드는 스트림 안에서 직접 사용할 수 없기 때문에 자바 8부터는 부담이 더욱 커졌다. 비..

[Effective Java] item 85. 자바 직렬화의 대안을 찾으라

[Effective Java] item 85. 자바 직렬화의 대안을 찾으라 직렬화란? java.io.Serializable 인터페이스를 상속받은 객체를 외부의 자바 시스템에서도 사용할 수 있도록 byte 형태로 데이터를 변환하는 기술 역직렬화는 반대로 byte로 변환된 data를 Object로 변환하는 기술 public class Member implements Serializable { private String name; private String email; private int age; public Member(String name, String email, int age) { this.name = name; this.email = email; this.age = age; } @Override p..

[Effective Java] item 78. 공유 중인 가변 데이터는 동기화해 사용하라

[Effective Java] item 78. 공유 중인 가변 데이터는 동기화해 사용하라 synchronized 키워드 해당 메서드나 블록을 한번에 한 스레드씩 수행하도록 보장한다. 1. synchronized 키워드를 사용하는 이유 1.1 배타적 실행 보장 한 스레드가 변경하는 중이라서 상태가 일관되지 않은 순간의 객체를 다른 스레드가 보지 못하게 막는 용도 한 객체가 일관된 상태를 가지고 생성되면 이 객체에 접근하는 메서드는 그 객체에 락(lock)을 건다. 락을 건 메서드는 객체의 상태를 확인하고 필요하면 수정한다. 즉, 객체를 하나의 일관된 상태에서 다른 일관된 상태로 변화시킨다. 동기화를 제대로 사용하면 어떤 메서드도 이 객체의 상태가 일관되지 않은 순간을 볼 수 없을 것이다.1.2 스레드 사이..

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

[Effective Java] item 70. 복구할 수 있는 상황에는 검사 예외를, 프로그래밍 오류에는 런타임 예외를 사용하라 자바에서 문제 상황을 알리는 타입(throwable) 1. 검사 예외 호출하는 쪽에서 복구하리라 여겨지는 상황이라면 검사 예외를 사용하라. 검사 예외를 던지면 호출자가 그 예외를 catch로 잡아 처리하거나 더 바깥으로 전파하도록 강제하게 된다. 따라서 메서드 선언에 포함된 검사 예외 각각은 그 메서드를 호출했을 때 발생할 수 있는 유력한 결과임을 API 사용자에게 알려주는 것이다. 달리 말하면, API 설계자는 API 사용자에게 검사 예외를 던져주어 그 상황에서 회복해내라고 요구한 것이다. 물론 사용자는 예외를 잡기만 ㅎ가ㅗ 별다른 조치를 취하지 않을 수도 있지만, 이는 보통..

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

[Effective Java] item 69. 예외는 진짜 예외 상황에만 사용하라 예외를 잘못 사용한 예시 운이 없다면 언젠가 다음과 같은 코드와 마주칠지도 모른다. 예외를 완전히 잘못 사용한 예 - 따라 하지 말 것! try { int i = 0; while (true) range[i++].climb(); } catch (ArrayIndexOutOfBoundsException e) { } 무슨 일을 하는 코드인지 알겠는가? 전혀 직관적이지 않다는 사실 하나만으로도 코드를 이렇게 작성하면 안 되는 이유는 충분하다. 이 코드는 배열의 원소를 순회하는데, 아주 끔찍한 방식으로 하고 있다. 무한 루프를 돌다가 배열의 끝에 도달해 ArrayIndexOutOfBoundsException이 발생하면 끝을 내는 것이..

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

[Effective Java] item 68. 일반적으로 통용되는 명명 규칙을 따르라 자바 플랫폼은 명명 규칙이 잘 정립되어 있으며, 그중 많은 것이 자바 언어 명세에 기술되어 있다. 자바의 명명 규칙은 크게 철자와 문법, 두 범주로 나뉜다. 철자 규칙 패키지, 클래스, 인터페이스, 메서드, 필드, 타입 변수의 이름을 다룬다. 이 규칙들은 특별한 이유가 없는 한 반드시 따라야 한다. 이 규칙을 어긴 API는 사용하기 어렵고, 유지보수하기 어렵다. 철자 규칙이나 문법 규칙을 어기면 다른 프로그래머들이 코드를 읽기 번거로울 뿐만 아니라 다른 뜻으로 오해할 수도 있고 그로 인해 오류까지 발생할 수 있다. 패키지와 모듈 이름 패키지와 모듈 이름은 각 요소를 점(.)으로 구분하여 계층적으로 짓는다. 요소들은 모두..

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

[Effective Java] item 67. 최적화는 신중히 하라 최적화 격언 (맹목적인 어리석음을 포함해) 그 어떤 핑꼐보다 효율성이라는 이름 아래 행해진 컴퓨터 죄악이 더 많다(심지어 효율을 높이지도 못하면서). - 윌리엄 울프(Wulf72) (전체의 97% 정도인) 자그마한 효율성은 모두 잊자. 섣부른 최적화가 만악의 근원이다. - 도널드 크누스(Knuth74) 최적화를 할 때는 다음 두 규칙을 다르라. 첫 번째, 하지 마라. 두 번째, (전문가 한정) 아직 하지 마라. 다시 말해, 완전히 명백하고 최적화되지 않은 해법을 찾을 때까지는 하지 마라. 이 격언들은 자바가 탄생하기 20년 전에 나온 것으로, 최적화의 어두운 진실을 이야기해준다. 최적화는 좋은 결과보다는 해로운 결과로 이어지기 쉽고, 섣..

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

[Effective Java] item 66. 네이티브 메서드는 신중히 사용하라 자바 네이티브 인터페이스(Java Native Interface, JNI)란? 자바 프로그램이 네이티브 메서드를 호출하는 기술 네이티브 메서드란, C나 C++같은 네이티브 프로그래밍 언어로 작성한 메서드 네이티브 메서드의 주요 쓰임 세 가지 1. 레지스트리 같은 플랫폼 특화 기능 사용 자바가 성숙해지면서 (OS 같은) 하부 플랫폼의 기능들을 점차 흡수하고 있다. 그래서 네이티브 메서드를 사용할 필요가 계속 줄어들고 있다. 예컨대 자바 9는 새로 processAPI를 추가해 OS 프로세스에 접근할 수 있는 길을 열어주었다. Java 9 Process API public class JavaProcess { public stati..

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

[Effective Java] item 65. 리플렉션보다는 인터페이스를 사용하라 리플렉션(reflection)란? 리플렉션 기능(java.lang.reflect)을 이용하면 프로그램에서 임의의 클래스에 접근할 수 있다. Class 객체가 주어지면 그 클래스의 생성자, 메서드, 필드에 해당하는 Constructor, Method, Field 인스턴스를 가져올 수 있고, 이어서 이 인스턴스들로는 그 클래스의 멤버 이름, 필드 타입, 메서드 시그니처 등을 가져올 수 있다. 나아가 Constructor, Method, Field 인스턴스를 이용해 각각에 연결된 실제 생성자, 메서드, 필드를 조작할 수 있다. 이 인스턴스들을 통해 해당 클래스의 인스턴스를 생성하거나, 메서드를 호출하거나, 필드에 접근할 수 있다..

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

[Effective Java] item 64. 객체는 인터페이스를 사용해 참조하라 객체는 클래스가 아닌 인터페이스로 참조하라 아이템 54에서 매개변수 타입으로 클래스가 아니라 인터페이스를 사용하라고 했다. 이 조언을 "객체는 클래스가 아닌 인터페이스로 참조하라"고까지 확장할 수 있다. 적합한 인터페이스만 있다면 매개변수뿐 아니라 반환값, 변수, 필드를 모두 인터페이스 타입으로 선언하라. 객체의 실제 클래스를 사용해야 할 상황은 '오직' 생성자로 생성할 때 뿐이다. 예를 들어 다음은 Set 인터페이스를 구현한 LinkedHashSet 변수를 선언하는 올바른 모습이다. // 좋은 예. 인터페이스를 타입으로 사용했다. Set sonSet = new LinkedHashSet(); // 나쁜 예. ..