본문 바로가기

이펙티브 자바13

[Effective Java] 아이템9 try-finally 보다는 try-with-resources를 사용하라 ■ 자원 닫기 자바 라이브러리에서는 close 메서드를 호출해 직접 닫아줘야 하는 자원이 많다. InputStream, OutputStream, java.sql.Connection 등이 좋은 예이다. 클라이언트가 놓치기 쉬워서 예측할 수 없는 성능 문제로 이루어지기도 한다. 이런 자원 중 상당수가 안전망으로 finallizer를 활용하지만 그리 믿을만하지 못하다. ■ try-finally를 이용한 자원 닫기 아래 코드는 닫을 자원이 1개일 때 try-finally를 사용해서 닫는 예시 코드 이다. static String firstLineOfFile(String path) throws IOException { BufferedReader br = new BufferedReader(new FileReader.. 2021. 1. 24.
[Effective Java] 아이템10 equals는 일반 규약을 지켜 재정의하라 ■ equals를 재정의 하지 않는게 좋은 상황 각 인스턴스가 본질적으로 고유할 때 값 클래스가 아닌 동작하는 개체를 표현하는 클래스 (Bean 해당) 인스턴스의 논리적 동치성을 검사할 일이 없을 때 자바 Pattern은 equals를 재정의 하여도 Pattern의 정규 표현식을 비교 상위 클래스에 재정의한 equals가 하위 클래스에 맞을 때 Set은 AbstractSet이 구현한 equals를 상속. List는 AbstractList, Map은 AbstractMap의 equals를 상속한다. 클래스가 private나 package-private이고 equals를 호출할 일이 없을 때 ■ equals를 재정의 해야 하는 경우 두 객체의 주소가 같은지 비교해야하는게 아니라 '논리적 동치성'을 확인해야하는.. 2021. 1. 22.
[Effective Java] 아이템8 finalizer와 cleaner 사용을 피하라 ■ 객체 소멸자 자바에서는 두 가지 객체 소멸자를 제공한다. 오브젝트 클래스에 포함된 finalize 메서드와 Java 9에서 추가된 java.lang.ref 패키지에포함된 Cleanner 클래스가 있다. 두 가지 모두 JVM에서 Garbage Collector가 수행될 때 실행되는 구문이다. 그런데 finalize 메서드는 Java 9에서 Deprecated 되었다. 또한 새로 추가된 Cleaner의 경우도 사용을 권장하지 않는다. ■ 사용 지양 이유 사용 했을 때 실행 시점을 보장할 수 없다. 실행 조차 안될 수 있다. 즉시 실행이 안되는 것을 감안하더라도 프로그램이 비정상 종료된다는 등의 이유로 실행조차 안될 수도 있다. 특정 시점 또는 반드시 실행되어야 한다는 것을 기대하고 사용해서는 안된다. 역.. 2021. 1. 21.
[Effective Java] 아이템5 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라 많은 클래스가 하나 이상의 자원(Resource)에 의존한다. 간혹 정적 유틸리티나 싱글턴에서 이러한 자원을 내부적으로 명시하고 있는 경우가 있다. 아래 예시 코드에서는 두 방식 모두 사전을 하나만 사용한다. 실전에서는 사전이 언어별로 따로 있고 특수 어휘용 사전을 별도로 두기도 하기 때문에 사전 하나로 대응 하나로 모든걸 대응한다는건 안좋은 설계이다. 정적 유틸리티를 잘못 사용한 예시 코드 // 정적 유틸리티 - 잘못된 예 public class SpellChecker { private static final Lexicon dictionary = new Lexicon(); // 특정 자원을 명시 private SpellChecker() {} // 인스턴스화 방지 - 아이템 4 // ...생략... } .. 2021. 1. 14.
[Effective Java] 아이템4 인스턴스화를 막으려거든 private 생성자를 사용하라 1. 정적 메서드와 정적 필드만 담은 클래스 생성 정적 메서드와 정적 필드만 담을 클래스 또는 final 클래스와 관련한 메서드들을 모아놓을 경우가있다. 정적 멤버만 담은 유틸리티 클래스는 인스턴스로 만들어 쓰려고 설계한게 아니기 때문에 private 생성자를 사용하면 된다. 예를들면 java.util.Collections 처럼 특정 인터페이스를 구현하는 객체를 생성해주는 정적 메서드를 모아놓는 경우 private 생성자를 사용한다. private 생성자에 이런 주석을 담으면 의도를 좀 더 명확하게 할 수 있다. //기본 생성자가 만들어지는 것을 막는다.(인스턴스화 방지용) private Collections() { } 2.정리 클래스의 인스턴스화를 막으려면 private 생성자를 추가하면 된다. pri.. 2021. 1. 13.
[Effective Java] 아이템2 생성자에 매개변수가 많다면 빌더를 고려하라 1. 정적 팩터리와 생성자의 문제점 정적 팩터리와 생성자는 선택적 매개변수가 많을 때 적절히 대응하기 어렵습니다. 대부분 점층적 생성자 패턴을 즐겨 사용하는데 이런 생성자는 사용자가 설정하고 싶지 않은 매개변수까지 포함하기 때문에 어쩔 수 없이 그런 매개변수도 값을 지정해줘야한다. 매개변수가 늘어날수록 걷잡을 수 없다. 2. 자바빈즈패턴 두번째 대안인 자바빈즈패턴을 사용하면 매개변수가 없는 생성자로 객체를 만든 후 세터 메서드들을 호출하여 원하는 매개변수의 값을 설정하는 방식이 있다. 자바빈즈패턴은 객체 하나를 만들려면 메서들르 여러번 호출해야하고 객체가 완전히 생성되기 전까지는 일관성이 무너진 상태에 놓이게 된다. 일관서이 깨진 객체가 만들어지면 버그를 심은 코드와 그 버그 때문에 런타임에 문제를 겪는.. 2021. 1. 12.