Effective Java
  • 예외의 상세 메시지 권장 예외를 잡지 못해 프로그램이 실패하면 자바 시스템은 그 예외의 스택 추적(stack trace) 정보를 자동으로 출력한다. 스택 추적은 예외 객체의 toString 메서드를 호출하여 얻는 문자열이다. 이 정보가 실패 원인을 분석하는 유일한 정보인 경우가 많으며 해당 실패를 재현하기 어렵다면 더 자세한 정보를 얻기가 어렵거나 불가능하다. 따라서 예외의 toString 메서드에 실패 원인에 관한 정보를 가능한 한 많이 담아 반환하는 일이 아주 중요하다. 사후 분석을 위해 실패 순간의 상황을 정확히 포착해 예외의 상세 메시지에 담아야한다. 실패 순간을 포착하려면 발생한 예외에 관여된 모든 매개변수와 필드의 값을 실패 메시지에 담아야한다. 예외가 발생한 원인은 제각각이므로, 예외의 상세..

    Read more
  • 예외 문서화 메서드가 던지는 예외는 그 메서드를 올바로 사용하는데 아주 중요한 정보다. 따라서 각 메서드가 던지는 예외 하나하나를 문서화해야한다. 검사 예외는 항상 따로따로 선언하고, 각 예외가 발생하는 상황을 자바독의 @throws 태그를 사용하여 정확히 문서화하자. Integer.java /** * Constructs a newly allocated {@code Integer} object that * represents the {@code int} value indicated by the * {@code String} parameter. The string is converted to an * {@code int} value in exactly the manner used by the * {@cod..

    Read more
  • 예외 번역 수행하려는 일과 관련 없어 보이는 예외가 발생하면 당황스럽다. 메서드가 저수준 예외를 처리하지 않고 바깥으로 전파해버릴대 종종 일어나는 일이다. 이는 내부 구현 방식을 드러내어 윗 레벨 API를 오염시킨다. 다음 릴리스에서 구현 방식을 바꾸면 다른 예외가 튀어나와 기존 클라이언트 프로그램을 깨지게 할 수도 있다. 상위 계층에서는 저수준 예외를 잡아 자신의 추상화 수준에 맞는 예외로 바꿔 던져야 한다. 이를 예외 번역(exception translation)이라 한다. 예외 번역 예시 try { ... // 저수준 추상화를 이용한다. } catch (LowerLevelException e) { /* 추상화 수준에 맞게 번역한다. */ throw new HigherLevelException(.....

    Read more
  • 예외 재사용의 이점 예외는 재사용하는 것이 좋다. 자바 라이브러리는 대부분 API에서 쓰기에 충분한 수의 예외를 제공한다. 표준 예외를 재사용하면 얻는게 많다. 1) 개발한 API가 다른 사람이 익히고 사용하기가 쉬워진다. 2) API를 사용한 프로그램도 낯선 예외를 사용하지 않게 되어 읽기 쉽게 된다. 3) 예외 클래스 수가 적을수록 메모리 사용량도 줄고 클래스를 적재하는 시간도 적게 걸린다. 가장 많이 재사용되는 예외는 IllegalArgumentException이다. 호출자가 인수로 부적절한 값을 던질때 던지는 예외다. Exception, RunTimeException, Throwable, Error는 직접 재사용하지 말자. 널리 재사용되는 예외 예외 주요 쓰임 IllegalArgumentExcep..

    Read more
  • 검사 예외 사용 지양 검사 예외는 발생한 문제를 프로그래머가 처리하여 안전성을 높이게끔 해준다. 물론, 검사 예외를 과하게 사용하면 오히려 쓰기 불편한 API가 된다. 어떤 메서드가 검사 예외를 던질 수 있다고 선언됐다면, 이를 호출하는 코드에서는 catch 블록을 두어 처리하거나 더 바깥으로 던져 문제를 전파해야한다. (throws Exception) 어느 쪽이든 API 사용자에게 부담을 준다. 더구나 검사 예외를 던지는 메서드는 스트림 안에서 직접 사용할 수 없어서 자바 8부터는 부담이 더 커졌다. 1) API를 제대로 사용해도 발생할 수 있는 예외 2) 프로그래머가 의미있는 조치를 취할 수 있는 경우 이 두가지 경우를 제외하고는 검사 예외보다는 비검사 예외를 사용하는게 좋다. 검사 예외가 프로그래머..

    Read more
  • 문제상황 권고 타입 자바는 문제 상황을 알리는 타입(throwable)으로 아래 3가지를 제공한다. 1) 검사 예외 2) 런타임 예외 3) 에러 위 3가지를 어떤 상황에서 선택해서 사용해야할지 헷갈린다. 이에 도움이 될 수 있는 지침을 살펴보자. 검사 예외 1) 호출하는 쪽에서 복구하리라 여겨지는 상황일 경우 이는 검사와 비검사 예외를 구분하는 기본 규칙이다. 검사 예외를 던지면 호출자가 그 예외를 catch로 잡아 처리하거나 더 바깥으로 전파하도록 강제하게된다. 따라서 메서드 선언에 포함된 검사 예외 각각은 그 메서드를 호출했을 때 발생할 수 있는 유력한 결과임을 API 사용자에게 알려주는 것이다. API 설계자는 API 사용자에게 검사 예외를 던져주어 그 상황에서 회복해내라고 요구한 것이다. 호출한 ..

    Read more
  • 예외의 잘못된 사용 결론적으로 잘못된 코드. 느리다. package com.java.effective.item68; public class Main { public static void main(String[] args) { try { int i = 0; while(true) { range[i++].climb(); } } catch (ArrayIndexOutOfBoundsException e) { } } } 위 코드는 직관적이지 않다. 해당 코드는 배열을 무한루프로 순회하다가 배열의 끝에 도달하여 ArrayIndexOutOfBoundsException이 발생하면 끝을 낸다. 표준적은 관용구 코드로 수정 package com.java.effective.item68; public class Main { pu..

    Read more
  • 자바의 명명규칙 자바 플랫폼은 명명 규칙이 잘 정립되어 있으며, 그중 많은 것이 자바 언어 명세에 기술되어있다. 자바의 명명 규칙은 크게 철자와 문법, 두 범주로 나뉜다. 철자 규칙 패키지, 클래스, 인터페이스, 메서드, 필드, 타입 변수의 이름을 다룬다. 이 규칙들은 특별한 이유가 없는 한 무조건 따라야한다. 1) 패키지와 모듈 이름은 각 요소를 점(.)으로 구분하여 계층적으로 짓는다. 요소들은 모두 소문자 알파벳 혹은 드물게 숫자로 이뤄진다. 2) 표준 라이브러리와 선택적 패키지들은 각각 java, javax로 시작한다. 3) 패키지 이름의 나머지는 해당 패키지를 설명하는 하나 이상의 요소로 이뤄진다. 각 요소는 일반적으로 8자 이하의 짧은 단어로 한다. utilities -> util 4) 패키지명..

    Read more
  • 자바 최적화 최적화는 신중히하자. 섣불리 진행하게되면 빠르지도 않고 제대로 동작하지도 않으면서 수정하기는 어려운 소프트웨어가 된다. 성능 때문에 견고한 구조를 포기하지말자. 빠른 프로그램보다는 좋은 프로그램을 작성하자. 프로그램을 완성할 때까지 성능 문제를 무시하라는 뜻이 아닌, 설계 단계에서 성능을 반드시 염두에 둬야한다는 말이다. 1) 성능을 제한하는 설계를 피하자. 완성 후 변경하기가 가장 어려운 설계 요소는 바로 컴포넌트끼리, 혹은 외부 시스템과의 소통 방식이다. API, 네트워크 프로토콜, 영구 저장용 데이터 포맷 등이 대표적이며, 이런 설계 요소들은 완성 후에는 변경하기가 어렵거나 불가능 할수도 있다. 2) API 설계할때 성능에 주는 영향을 고려하자. public 타입을 가변으로 만들면, 즉..

    Read more
  • 자바 네이티브 인터페이스(Java Native Interface, JNI) 자바 프로그램이 네이티브 메서드를 호출하는 기술이다. 네이티브 메서드 C, C++과 같은 네이티브 프로그래밍 언어로 작성한 메서드를 말한다. 네이티브 메서드의 쓰임 1) 레지스트리와 같은 플랫폼 특화 기능을 말한다. 2) 네이티브 코드로 작성된 기존 라이브러리를 사용한다. 레거시 데이터를 사용하는 레거시 라이브러리가 그 예다. 3) 성능 개선을 목적으로 성능에 결정적인 영향을 주는 영역만 따로 네이티브 언어로 작성한다. -> JVM에는 거의 해당되지 않는다. 플랫폼 특화 기능을 활용하려면 네이티브 메서드를 사용해야한다. 하지만 자바가 성숙해가면서 (OS 같은) 하부 플랫폼의 기능들을 점차 흡수하고있다. 그래서 네이티브 메서드를 사..

    Read more
  • 리플렉션 리플렉션 기능(java.lang.reflect)을 이용하면 프로그램에서 임의의 클래스에 접근할 수 있다. Class 객체가 주어지면 그 클래스의 생성자, 메서드 필드에 해당하는 Constructor, Method, Field 인스턴스를 가져올 수 있고, 이어서 이 인스턴스들로는 그 클래스의 멤버 이름, 필드 타입, 메서드 시그니처 등을 가져올 수 있다. 또한 각 인스턴스들을 사용하여 각각에 연결된 실제 생성자, 메서드, 필드를 조작할 수도 있다. 이 인스턴스들을 통해 해당 클래스의 인스턴스를 생성하거나, 메서드를 호출하거나, 필드에 접근할 수 있다. 리플렉션 단점 1) 컴파일타임 타입 검사가 주는 이점을 하나도 누릴 수 없다. 리플렉션 기능을 써서 존재하지 않는 혹은 접근할 수 없는 메서드를 호..

    Read more
  • 인터페이스 타입 사용 매개변수 타입으로 클래스가 아니라 인터페이스를 사용해야한다. 또한 적합한 인터페이스만 있다면, 매개변수 뿐만 아니라 반환값, 변수, 필드를 전부 인터페이스 타입으로 선언하라. 객체의 실체 클래스를 사용해야할 상황은 오직 생성자로 생성할때 뿐이다. 좋은 예. 인터페이스를 타입으로 사용 Set test = new LinkedHashSet(); 나쁜 예. 클래스를 타입으로 사용 LinkedHashSet test = new LinkedHashSet(); 인터페이스를 타입으로 사용하는 습관을 길러두면 프로그램이 훨씬 유연해질 수 있다. 만약 구현 클래스를 교체하고자한다면 그저 새 클래스의 생성자(혹은 다른 정적 팩터리)를 호출해주기만 하면 된다. 구현 클래스 유연하게 변경 Set test =..

    Read more
  • 문자열 연결시 String 대신 StringBuilder을 사용 권장 문자열 연결 연산자(+)는 여러 문자열을 하나로 합쳐주는 편리한 수단이다. 이는 한줄짜리 출력값 혹은 작고 크기가 고정된 객체의 문자열 표현을 만들때는 괜찮지만, 본격적으로 사용하기 시작하면 성능 저하를 감내하기 어렵다. 문자열 연결 연산자로 문자열 n개를 잇는 시간은 n의 제곱에 비례한다. 문자열은 불변이라서 두 문자열을 연결할 경우 양쪽의 내용을 모두 복사하므로 성능 저하를 피할 수 없는 결과다. 문자열 연결을 잘못 사용한 예시 - 느리다 package com.java.effective.item63; public class Main { public static void main(String[] args) { } public Stri..

    Read more
  • 문자열을 쓰지않아야할 사례 문자열(String)은 텍스트를 표현하도록 설계되었다. 자바에서 문자열을 의도하지 않은 용도로도 쓰이는 경향이 있는데, 문자열을 쓰지 않아야할 사례에 대해 알아보자. 1) 문자열은 다른 값 타입을 대신하기에 적합하지 않다. 많은 사람이 파일, 네트워크, 키보드 입력으로부터 데이터를 받을 때 주로 문자열을 사용한다. 입력받을 데이터가 진짜 문자열일 경우에만 사용해야한다. 받은 데이터가 수치형이라면 int, float, BigInteger 등 적당한 수치 타입으로 변환해야한다. 기본 타입이든 참조 타입이든 적절한 값 타입이 있다면 그것을 사용하고, 없다면 새로 하나 작성하라. 2) 문자열은 열거타입을 대신하기에 적합하지 않다. 문자열보다는 열거 타입이 월등히 낫다. 3) 문자열을 ..

    Read more
  • 기본타입과 박싱된 기본타입 자바이 데이터 타입은 크게 두가지로 나눌 수 있다. 바로 int, double, boolean과 같은 기본 타입과 String, List 같은 참조 타입이다. 각각의 기본 타입에 대응하는 참조 타입이 하나씩 존재하고, 이를 박싱된 기본타입이라고 한다. 기본타입 int, double, boolean 박싱된 기본 타입 Integer, Duble, Boolean 오토박싱과 오토언박싱 덕분에 두 타입을 크게 구분하지 않고 사용할 수는 있지만, 둘의 차이는 분명하다. 따라서 상황에 따라 주의해서 선택해야한다. 기본 타입과 박싱 기본타입의 차이 1) 기본 타입은 값만 가지고 있으나, 박싱된 기본 타입은 값에 더해 식별성이란 속성을 갖는다. 박싱된 기본 타입의 두 인스턴스는 값이 같아도 서..

    Read more
  • Copyright 2024. GRAVITY all rights reserved