본문 바로가기
[Effective Java] 공유하는 가변 데이터에 접근 시 동기화하자. [Effective Java] 공유하는 가변 데이터에 접근 시 동기화하자. - 동기화를 하지 않으면, 하나의 스레드에서 변경한 내용을 다른 스레드에서 못 볼 수 있다. 동기화는 불안정 상태의 객체를 스레드가 볼 수 없도록 하는 것은 물론, 동기화된 메소드나 블록에 진입하는 각 스레드가 앞에서의 모든 변경(같은 락으로 보호되었던)이 반영된 결과를 볼 수 있게 해준다. - 자바 언어 명세에서는 long 이나 double 타입이 아닌 변수의 값을 읽거나 쓸 때는 원자성을 보장한다. long 이나 double 타입이 아닌 변수의 값을 읽으면 어떤 스레드가 그 변수에 저장했던 값을 반환 받을 수 있다는 것. 실제로 동기화하지 않고 여러 스레드가 그 변수를 동시에 수정해도 그때그때 수정된 값이 반영된다. 스레드가 .. 2017. 3. 7.
[Effective Java] 실패 원자성을 갖도록 노력하자 [Effective Java] 실패 원자성을 갖도록 노력하자 - 일반적으로 호출된 메소드가 실행에 실패하더라도 객체 상태는 메소드 호출 전과 같아야 한다. 이런 특성을 갖는 메소드를 실패 원자성(failure atomic) 메소드라 한다. - 가장 간단한 방법은 불변 객체로 설계하는 것이다. 객체가 불변이면 실패 원자성과는 아예 무관하다. - 가변 객체를 처리하는 메소드의 경우에 실패 원자성을 성취하는 가장 보편적인 방법은 연산 수행 전에 매개 변수의 유효성을 검사하는 것이다. - 실패 원자성을 성취하는 더 좋은 방법은, 객체를 변경하는 코드 부분에 앞서 실패할 수 있는 코드 부분이 실행되도록 연산 순서를 조정하는 것이다. - 또 다른 방법은 ( 흔하지 않지만 ) 연산 도중에 발생하는 실패를 가로채는 복.. 2017. 3. 3.
[Effective Java] 메소드가 던지는 모든 예외를 문서화하자. [Effective Java] 메소드가 던지는 모든 예외를 문서화하자. - Javadoc 의 @throws 태그를 사용해서 항상 checked 예외는 별도로 선언하고, 각 예외가 발생하는 상황을 정확하게 문서화하자. 메소드가 던지는 예외가 많다고 해서 메소드 명세에 각 예외를 정확하게 선언하지 않고, 그 예외 클래스의 대표적인 슈퍼 클래스만 함축해서 나타내면 안 된다. - unchecked 예외의 문서 내역은 메소드가 성공적으로 실행되기 위한 사전조건(precondition)을 효과적으로 나타낸다. - 인터페이스에 정의된 메소드의 경우 자신이 던질 수 있는 unchecked 예외를 문서화하는 것이 "특히" 중요하다. 그 인터페이스의 보편적 계약 중 일부분이 되며, 인터페이스를 구현하는 여러 구현체들 간의.. 2017. 2. 28.
[Effective Java] 하위 계층의 예외 처리를 신중하게 하자. [Effective Java] 하위 계층의 예외 처리를 신중하게 하자. - 상위 계층에서 하위 계층의 예외를 반드시 catch 해야 한다. 그리고 그 예외대신에 상위 계층의 추상체가 알 수 있는 예외로 바꿔 던져야 한다. 이 이디엄을 예외 변환(exception translation)이라 한다. 그렇지 않으면 구현 내용을 공개하는 것처럼 되어 나중에 호환성 이슈를 겪게 된다. - 만약 예외 변환을 사용하면서 근본적인 이유까지 확실히 알고 싶다면 변화할 때 excpetion 을 담아서 전달할 수 있다. 예를 들어 throw new HigherLevelException( lowerLevelException ) - 예외 연쇄 - 하위 계층(저수준)에서 발생한 예외를 분별 없이 전파하는 것보다는 예외 변환을 사.. 2017. 2. 27.
[Effective Java] checked 예외의 불필요한 사용을 피하자 [Effective Java] checked 예외의 불필요한 사용을 피하자 - checked 예외는 프로그래머가 예외 상황을 처리하지 않을 수 없도록 한다. - checked 예외의 과용은 API 사용자를 불편하게 만든다. - 만일 API 사용자가 해당 예외 사항에 대해 ignore 와 같은 방식 이외에 해결방법이 없다면, unchecked 에러를 사용하는 게 더 적합하다. - checked 예외를 unchecked 예외로 바꾸는 한 가지 방법은, 해당 예외를 발생시키는 메소드를 두 개의 메소드로 쪼개는 것이다. 그 중 첫번째 메소드에서는 예외가 생겼는지를 나타내는 boolean 값을 반환하게 한다. 예를 들면.. try{obj.action(args);} catch( TheCheckedException .. 2017. 2. 23.
[Effective Java] 보편화된 작명 규칙을 따르자. [Effective Java] 보편화된 작명 규칙을 따르자. - 패키지 이름은 짧게 하되, 일반적으로 9자 이내의 문자가 좋다. awt와 같이 복합 단어의 첫 자를 딴 두문자나, util 과 같은 약어를 사용해도 좋다. - 타입 매개변수의 이름은 통상적으로 단일 문자이며, 대부분 다음 다섯 개 중 하나이다. 임의 타입은 T, 컬렉션 요소 타입은 E, Map 의 키와 값은 K, V, 예외는 X 임의 타입의 순차는 T에 이어 U, V 또는 T1, T2, T3 등과 같이 하기도 한다. - boolean 이 아닌 속성을 반환하는 메소드의 이름은 명사, 명사구, 또는 동사인 get 으로 시작하는 동사구로 구성한다. size, hashCode, getTime 등이 그 예이다. 이런 return 값이 있는 메소드들은.. 2017. 2. 17.
[Effecitve Java] 리플렉션보다는 인터페이스를 사용하자. [Effecitve Java] 리플렉션보다는 인터페이스를 사용하자. - 리플렉션은 여러모로 강력한 기능을 제공한다. 하지만 이런 강력함은 다음의 대가들을 수반한다. 컴파일 시점에 가능한 타입 확인의 장점이 없어진다. 재귀적인 접근을 필요로 하는 코드는 알아 보기 어렵고 길다. 처리 성능이 늦다. - 사실 리플렉션은 컴포넌트 기반의 어플리케이션 개발 도구용으로 설계되었다. 따라서 일반적으로 런타임에서는 리플렉션을 이용해서 재귀적으로 사용하면 안된다. - 리플렉션이 필요한 복잡한 애플리케이션은 다음과 같다. 클래스 브라우저 객체 조사기 코드 분석 도구 RPC - 리플렉션을 지극히 제한된 형태로만 사용하여 비용이 거의 수반되지 않도록 한다면 리플렉션의 많은 장점을 얻을 수 있다. 예를 들어 컴파일 시점에는 쓸.. 2017. 2. 13.
[Effective Java] 지역 변수의 유효 범위를 최소화 하자. [Effective Java] 지역 변수의 유효 범위를 최소화 하자. - 지역 변수의 유효 범위를 최소화하면, 코드의 가독성과 유지 보수성을 높이고 에러의 가능성이 줄어든다. - C와 같은 종전 프로그래밍 언어들은 지역 변수를 블록의 맨 앞에 선언해야 했으며, 일부 프로그래머들은 습관 때문에 계속 그렇게 한다. 하지만 이것은 버려야 할 습관이다. 자바에서는 명령문만 적법하다면 어디에든 변수를 선언할 수 있기 때문. - 지역 변수의 유효 범위를 최소화하는 가장 강력한 방법은 그 변수가 최초 사용되는 곳에 선언하는 것. 만일 변수를 사용하기 전에 선언하면 혼란만 생긴다. - 지역 변수의 선언과 초기화에 주의하자. 만일 변수를 올바르게 초기화하는데 필요한 정보가 충분하지 않다면, 충분하게 될 때 까지 선언을 .. 2017. 1. 24.
[Effective Java] 외부에 제공하는 모든 API 요소에 대해 문서화 주석을 넣자. [Effective Java] 외부에 제공하는 모든 API 요소에 대해 문서화 주석을 넣자. - 사용 가능한 API 라면 반드시 문서화해야 한다. 만일 문서화 주석 규칙에 친숙하지 않다면 배워야 한다. - API 를 문서화하려면, 외부에 제공하는 모든 클래스, 인터페이스, 생성자, 메소드, 필드의 선언부 앞에 문서화 주석을 넣어야 한다. 만일 어떤 클래스가 직렬화될 수 있다면 직렬화 형태도 문서화해야 한다. - 문서화 주석이 빠진 API 를 사용하는 것은 실망스럽고 에러가 생길 가능성이 많다. 유지보수 하기 쉬운 코드를 작성하려면 외부에 공개되지 않는 대부분의 클래스, 인터페이스, 생성자, 메소드, 필드에 대해서도 문서화 주석을 작성해야 한다. - 메소드의 문서화 주석에서는 메소드와 클라이언트 사이의 계.. 2017. 1. 23.
반응형