목록Effective Java (19)
개발일기
equals를 재정의한 클래스 모두에서 hashCode 재정의해야 한다- equals 비교에 사용되는 정보가 변경되지 않았다면, 애플리케이션이 실행되는 동안 그 객체 hashCode 메서드는 몇 번을 호출해도 일관되게 값은 값 반환- equals(Object) 두 객체가 같다고 판단, hashCode 똑같은 값을 반환- equals(Object)가 두 객체를 다르다고 판단했더라도, 두 객체의 hashCode 서로 다른 값을 반환할 필요는 없다. 단, 다른 객체에 대해서 다른 값 반환해야 성능 향상 hashCode 재정의 잘못했을 때 크게 문제가 되는 조항 두번째다. 즉 , 논리적으로 같은 객체는 같은 해시 코드를 반환해야한다.Map m = new HashMap();m.put(new PhoneNumber..
equals 메서드는 쉬워보이지만 곳곳에 함정이 도사리고 있어서 끔찍한 결과를 초래함. -> 문제 회피 가장 쉬운 길은 아예 재정의 xHashCode, Equals 재정의 하는게 좋은줄 알았는데.. 잘못알고 있었음. 재정의 하지 않아도 되는 경우1. 각 인스턴스가 본질적으로 고유 - 값 표현 x 동작하는 객체 표현 - Thread -> Object의 equals 이러한 클래스 용도 맞게 구현2. 인스턴스 '논리적 동치성(logical equality)' 검사 x - 두 Pattern의 인스턴스가 같은 정규 표현식 나타내는지를 검사 방법 즉, 논치적 동치성 검사 방법 => equals 필요 - 위에 방식이 필요하지 않다고 설계자가 후자로 판단 Object 기본 equals 해결3...
🔥 try-finally- 더 이상 자원을 회수하는 최선의 방책이 아니다! import java.io.BufferedReader;import java.io.FileReader;import java.io.IOException;static String firstLineOfFile(String path) throws IOException { BufferedReader br = new BufferedReader(new FileReader(path)); try { return br.readLine(); } finally { br.close(); }} ‼️ 자원이 둘 이상이면 try-finally 방식은 너무 지저분하다!import java.io.*;static v..
1. finalizer 예측할 수 없고, 상황에 따라 위험할 수 있어 일반적으로 불필요하다. => 해당은 자바18버전에서 삭제됨 - finalizer와 cleaner는 즉시 수행된다는 보장이 없다. - **finalizer와 cleaner로는 제때 실행되어야 하는 작업은 절대 할 수 없다.**2. finalizer와 cleaner 심각한 성능 문제도 동반3. finalizer를 사용한 클래스는 finalizer 공격에 노출되어 심각한 보안 문제를 일으킴4. 객체 생성을 막으려면 생성자에서 예외를 던지는 것만으로 충분하지만,finalizer가 있다면 그렇지도 않다.5. final이 아닌 클래스를 finalizer 공격으로부터 방어하려면 아무 일도 하지 않는 finalize 메서드를 만들고 fina..
import java.util.Arrays;import java.util.EmptyStackException;public class Stack { private Object[] elements; private int size; 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 Object pop() { if..
똑같은 기능의 객체를 매번 생성하기보다는 객체 하나를 재사용하자. 💡 주요 내용 정리String s = new String("bikini"); // 따라 하지 말 것! 해당 문장은 실행될 때마다 String 인스턴스를 만들어 인스턴스 낭비 static boolean isRomanNumeral(String s) { return s.matches("^(?=.)M*(C[MD]|D?C{0,3})" + "(X{CL}|L?X{0,3})(I[XV]|V?I{0,3})$");}String.matches는 정규표현식으로 문자열 형태를 확인하는 가장 쉬운 방법이지만, 성능이 중요한 상황에서 반복해 사용하기엔 적합xPattern 인스턴스는 한 번 쓰고 버려져서 곧바로 가비지 컬렉션 대상 import java.util..
많은 클래스가 하나 이상의 자원에 의존한다. 가령 맞춤법 검사기는 사전에(dictionary)에 의존하는데, 이런 클래스를 정적 유틸리티 클래스(아이템4)로 구현한 모습을 드물지 않게 볼 수 있다. 5-1 정적 유틸리티를 잘못 사용한 예 - 유연하지 않고 테스트하기 어렵다. public class SpellChecker { private static final Lexicon dictionary = ...; private SpellChecker() { } // 객체 생성 방지 public static boolean is Vaild (String word) public static List suggestions(String typo) {...} } 5-2 싱글턴을 잘못 사용한 예 - 유연하지 않고 테스트하기..
정적 메서드와 정적 필드만을 담은 클래스를 만들고 싶을 때가 있을 것이다. 객체 지향적으로 사고하지 않는 이들이 종종 남용하는 방식이기 때문에 그리 곱게 보이지는 않지만, 나름의 쓰임새가 있다. 1. java.lang.Math와 java.util.Arrays처럼 기본 타입 값이나 배열 관련 메서드들을 모아놓을 수 있다. 2. java.util.Collections처럼 특정 인터페이스를 구현하는 객체를 생성해주는 정적 메서드(혹은 팩터리) 를 모아 놓을 수 있음 3. 마지막으로, final 클래스와 관련한 메서드들을 모아놓을 때도 사용한다. final 클래스를 상속해서 하위 클래스에 메서드를 넣는 건 불가능하기 때문이다. 정적 멤버만 담은 유틸리티 클래스는 인스턴로 만들어 쓰려고 설계한게 아니다. 하지만 ..