본문 바로가기

728x90
반응형

책리뷰/이펙티브자바

(11)
[이펙티브자바] 아이템11. equals를 재정의하려거든 hashCode도 재정의하라 equals를 재정의할 때 hashCode를 재정의하지 않으면 HashMap이나 HashSet같은 컬렉션의 원소로 클래스의 인스턴스를 사용할 때 문제가 된다. Object 명세 규약 equals 비교에 사용되는 정보가 바뀌지 않으면 몇 번을 호출해도 hashCode는 같은 값을 리턴한다. 어플리케이션이 재실행되면 값이 달라질 수도 있다. equals(Object)가 두 객체를 같다고 판단하면 hashCode도 같아야 한다. equals가 다르다고 hashCode도 다른 값을 반환할 필요는 없다. 하지만 다른 값을 반환해야 해시테이블의 성능이 좋아진다. @Getter @Setter @AllArgsConstructor public class User { private int id; private int ph..
[이펙티브자바] 아이템10. equals는 일반 규약을 지켜 재정의하라 equals메서드는 많은 경우에 Object의 equals가 정확히 비교해주기 때문에 꼭 필요한 경우가 아니라면 재정의하지 말자. equals를 재정의 하지 말아야하는 경우 각 인스턴스가 본질적으로 고유하다. 인스턴스가 가지는 값보다 동작하는 개체임을 나타내는 게 더 중요한 클래스(Thread) Thread클래스는 Object의 equals로 충분함 인스턴스의 논리적 동치성을 검사할 일이 없다. java.util.regex.Pattern의 equals를 재정의해서 두 Pattern인스턴스가 같은 정규표현식을 나타내는지 검사할 필요가 없다. 상위 클래스에서 재정의한 equals가 하위클래스에도 딱 들어맞는다. 클래스가 private이거나 package-private이고 equals메서드를 호출할 일이 없다..
[이펙티브자바] 아이템9. try-finally보다는 try-with-resources를 사용하라 자바 라이브러리에서 close메서드를 호출해 직접 자원을 닫아 줘야하는 경우가 있다. (InputStream, OutputStream, java.sql.Connection 등..) 자원을 닫을 때 finalizer는 믿을 수 없다. 2022.02.24 - [책리뷰/이펙티브자바] - [이펙티브자바] 아이템8. finalizer와 cleaner사용을 피하라 전통적인 방법으로는 try-finally가 쓰였다. try-finally 구문의 문제 static String firstLineOfFile(String path) throws IOException { BufferedReader br = new BufferedReader(new FileReader(path)); try { return br.readLine(..
[이펙티브자바] 아이템8. finalizer와 cleaner사용을 피하라 자바에서는 두 가지 객체 소멸자를 제공하는데 Finalizer는 예측불가능하고 위험하며 대부분 불필요하다. 자바9에서 deprecated되었다. 그 대안으로 Cleaner를 사용하는데 Finalizer보다는 덜 위험하지만 예측불가능하며, 느리고, 불필요하다. 자바에서 접근할 수 없는 객체 자원을 회수하는 역할은 GC가 한다. 비메모리 자원을 회수하기 위해서는 try-with-resource, try-finally를 사용해 해결한다. 사용을 피해야하는 이유1 언제 수행될지 모른다. finalizer와 cleaner로 제때 실행되어야하는 작업은 절대 할 수 없다. 타이밍이 중요한 작업은 절대 사용하면 안된다. 예를 들어, 파일 닫기를 처리한다면 시스템이 finalizer나 cleaner실행을 게을리 해서 동..
[이펙티브자바] 아이템7. 다 쓴 객체 참조를 해제하라 자바에서는 다쓴 객체를 알아서 회수해가는 가비지 컬렉터가 있다. 자칫 메모리 관리에 신경을 쓰지 않아도 된다고 오해할 수 있는데 절대 아니다. Stack클래스의 메모리 누수 public class Stack { private Object[] elements; private int size = 0; // 처음 stack 사이즈 private static final int DEFAULT_INITIAL_CAPACITY = 16; public Stack() { elements = new Object[DEFAULT_INITIAL_CAPACITY]; } public void push(Object e) { ensureCapacity(); // 배열 사이즈 체크 elements[size++] = e; } public ..
[이펙티브자바] 아이템6. 불필요한 객체 생성을 피하라 똑같은 기능을 하는 객체는 매번 생성하기보다 재사용하는 편이 빠르고 세련되다. String s = new String("bikini"); String s = "bikini"; 첫 번째 코드는 실행될 때마다 String 인스턴스를 새로 만들고 두 번째 코드는 하나의 String인스턴스를 재사용한다. 정적 팩터리 메서드 사용 생성자 대신 정적팩터리 메서드를 사용하면 불필요한 객체 생성을 막을 수 있다. Boolean(String) 생성자 대신 Boolean.valueOf(String)팩터리 메서드 사용하는 것이 좋은 예이다. (생성자는 자바9에서 deprecated됨) 생성 비용이 비싼 객체 사용 지양 static boolean isRomanNumeral(String s) { return s.matches(..
[이펙티브자바] 아이템5. 의존 객체 주입을 사용해라. 많은 클래스가 하나이상의 자원에 의존한다. 정적 유틸리티 클래스를 예로 들어볼 수 있다. 정적유틸리티 잘못 사용한 예 - 유연하지 않고 테스트 하기 어렵다. public class SpellChecker { private static final Lexicon dictionary = ..; private SpellChecker() {} public static boolean isValid(String word) { ...} public static List suggestions(String typo) { ...} } 싱글턴을 잘못 사용한예 - 유연하지 않고 테스트 어렵다 public class SpellChecker { private static final Lexicon dictionary = ...; p..
[이펙티브자바] 아이템4. 인스턴스화를 막으려면 private을 강제하라 정적메서드와 정적 필드만을 담은 클래스를 만들고 싶을 때가 있다. 예를 들면 java.lang.Math, java.util.Arrays와 같은 기본 타입의 값이나 배열 관련 메서드를 모아놓을 수 있다. java.util.Collections처럼 특정 인터페이스를 구현하는 객체를 생성해주는 정적 메서드를 모아놓을 수도 있다. 컴파일러는 생성자를 명시하지 않으면 public 생성자를 만들어준다. 의도하지 않아도 인스턴스화할 수 있게 된다. public class UtilClass { public static String getName() { return "heypli"; } public static void main(String[] args) { UtilClass utilClass = new UtilClas..

728x90
반응형