목록이펙티브자바 (88)
도당탕탕
표준 exception 사용의 장점 표준이기 때문에, 다른 사람이 API를 익히기 쉽다. Exception 클래스의 종류가 적어지면 memory footprint가 줄어들고 클래스를 로딩하는데 시간이 덜 걸린다. 주의할 점 Exception, RuntimeException, Throwable, Error 클래스들은 다른 exception들의 super class 이기 때문에 직접 사용해서는 안된다. 표준 exception에서 추가로 구현을 하고 싶다면 상속을 받아서 구현을 해도 된다. Exception은 serializable 이기 때문에 꼭 필요한 경우가 아니면, 새로운 exception 클래스를 구현하지 말아야 한다. IllegalArgumentException 과 IllegalStateExcepti..
검사 예외를 싫어하는 자바프로그래머가 많지만 제대로 활용하면 API와 프로그램의 질을 높일 수 있다. 검사 예외를 사용하면 문제를 프로그래머가 처리하여 안정성을 높이게끔 해주지만, 과하게 사용하면 오히려 쓰기 불편한 API가 된다. 어떤 메서드에서 검사 예외를 과하게 사용하면 이를 호출하는 코드에서 catch 블록을 두어 그 예외를 붙잡아 처리하거나, 더 바깥으로 던져 문제를 전파해야만 한다. 더욱이 자바 8에 stream에서는 직접 사용할 수 없기 때문에 부담이 더욱 커졌다. 검사 예외의 문제 API를 제대로 사용해도 발생할 수 있는 예외이거나, 프로그래머가 의미 있는 조치를 취할 수 있는 정도라면 이 정도의 부담쯤은 받아들일 수 있을 것이다. 하지만 그렇지 않더라면 비검사 예외를 사용하는 게 좋다. ..
세 가지 유형의 throwables checked exception 사용자는 반드시 catch문으로 exception을 핸들링 해야한다. 사용자는 exception에 대한 해결로직을 구현해야 한다. Exception 클래스를 상속받는다. unchecked throwable 절대 catch 하면 안 된다. 보통 exception 회복이 불가능하다고 판단 또는 계속되는 실행이 더 시스템에 악영향을 준다. runtime exception 결국 현재 스레드가 죽고, 에러를 출력한다. 주로 프로그래밍 에러를 나타내기 위해서 사용한다.(예 : ArrayIndexOutOfBounds) RuntimeException을 상속받는다. error error는 보통 JVM이 사용하도록 예약되어 있다. 보통 리소스 부족, in..
예외를 완전히 잘못 사용한 예 try { int i = 0; while(true) range[i++].climb(); } catch (ArrayIndexOutOfBoundException e) { ... } 위 코드는 전혀 직관적이지 않기 때문에 이렇게 코드를 작성하면 안 된다는 것을 보여준다. 이 코드는 배열의 원소를 순회하는데, 무한 루프를 돌다가 배열의 끝에 도달해 ArrayIndexOutOfBoundsException을 발생시켜 끝내는 코드이다. 이 코드를 다음과 같이 표준적인 관용구대로 작성했다면 모든 자바 프로그래머가 이해했을 것이다. 올바른 예제 for (Mountion m : range) m.climb(); 그런데 왜 예외를 써서 루프를 종료시키려 했던 것일까? 그 이유는 다음과 같다. J..
Java Language Specification (JLS, 6.1)에는 잘 만들어진 네이밍 컨벤션이 있다. 네이밍 컨벤션은 2가지 카테고리로 나눌 수 있다. 활자관점에서의 컨벤션 패키지의 모듈 이름은 계층 구조이어야 하고 점으로 구분되어야 함. 클래스, 인터페이스에서 첫 번째 글자는 대문자 이어야 함. 메서드와 필드이름의 첫 글자는 소문자 이어야 함. 지역변수는 약어를 권장함. Type 파라미터 T : any type E : Element type K, V : Key, Value type X : exception type R : return type 문법관점에서의 컨벤션 유연하고 논란의 여지가 있음. 객체화 가능한 클래스는 명사나 명사구로 만듦.(Thread, PriorityQueue,...) 객체화 ..
다음 최적화 격언 3가지를 소개한다. 1. (맹목적인 어리석음을 포함해) 그 어떤 핑계보다 효율성이라는 이름 아래 행해진 컴퓨팅 죄악이 더 많다. (심지어 효율을 높이지도 못하면서) -- 윌리엄 울프 -- 2. (전체의 97% 정도인) 자그마한 효율성은 모두 잊자. 섣부른 최적화가 만악의 근원이다. -- 도널드 크누스 -- 3. 최적화를 할 때는 다음 두 규칙을 따르라. 첫 번째, 하지 마라. 두 번째, (전문가 한정) 아직 하지 마라. 다시 말해, 완전히 명백하고 최적화되지 않은 해법을 찾을 때까지는 하지 마라. -- M. A. 잭슨 이 격언들은 자바가 탄생하기 20년전에 나온 것으로, 최적화의 어두운 진실을 이야기해 준다. 최적화는 좋은 결과보다는 해로운 결과로 이어지기 쉽고, 섣불리 진행하면 특히 ..
JNI(Java Native Interface)는 자바 프로그램에서 native method를 호출할 수 있게 해 준다. Platform specific 기능들에 접근하기 위해서 native method를 사용하는 것은 합법적이지만 대부분 그럴 필요가 없다. Java에서 이미 같은 기능을 구현한 라이브러리가 있는 경우가 대부분이기 때문이다. 예전에는 성능 최적화를 위해서, native 라이브러리를 사용하기도 했지만, 이제는 Java 라이브러리가 성능이 개선이 되었기 때문에 사용할 필요가 없어졌다. 예를 들어, BigInteger 클래스의 경우가 그렇다. Native method의 단점 메모리 corruption error에 취약해진다. garbage collector가 관리해주지 못한다. memory c..
리플렉션 기능을 이용하면 프로그램에서 임의의 클래스에 접근할 수 있다. Class객체가 주어지면 그 클래스의 생성자, 메서드, 필드에 해당하는 인스턴스를 가져올 수 있다. 또한 이 인스턴스들로는 그 클래스의 멤버 이름, 필드 타입, 메소드 시그니처 등을 가져올 수 있고 조작도 가능하다. 예를 들어 Method.invoke는 어떤 클래스의 어떤 객체가 가진 어떤 메소드라도 호출할 수 있게 해 준다. 이렇게 리플렉션을 이용하면 컴파일 당시에 존재하지 않던 클래스도 이용할 수 있는데, 다음과 같이 단점이 있다. 컴파일타임 타입 검사가 주는 이점을 하나도 누릴 수 없다. 예외 검사도 마찬가지로, 프로그램이 리플렉션 기능을 써서 존재하지 않는 혹은 접근할 수 없는 메서드를 호출하려 시도하면 런타임 오류가 발생한다..