JAVA/Effective Java 90

[아이템 10] equals는 일반 규약을 지켜 재정의하라

모든 클래스는 암묵적으로 Object 클래스를 상속하며 이에 따라 아래의 메서드를 오버라이딩 가능합니다. equals hashcode toString clone finalize 이번 게시글에서는 equals에 대해 알아보겠습니다. equals를 재정의할 필요 없는 케이스 아래의 케이스에 대해서는 equals를 재정의할 필요가 없습니다. 각 인스턴스가 본질적으로 고유 인스턴스의 "논리적 동치성"을 검사할 필요 없음 상위 클래스에서 재정의한 equals가 하위 클래스에도 적절 클래스가 private이거나 package-private이고 equals 메서드를 호출할 일 없음 1. 각 인스턴스가 본질적으로 고유 싱글톤으로 구현했거나 enum 클래스일 경우 본질적으로 고유한 인스턴스이기 때문에 비교를 하는 경우가..

JAVA/Effective Java 2024.01.26

[아이템 9] try-finally보다는 try-with-resources를 사용하라

Java 7부터 try-with-resources 구문이 등장해 try-finally는 더 이상 최선의 방법이 아닙니다. try-with-resources를 사용할 경우 장점은 아래와 같습니다.코드가 훨씬 간결해져 가독성이 좋아짐예외가 두 개 이상 발생했을 때 예외를 잡아먹지 않기 때문에 전부 확인 가능 코드가 훨씬 간결해져 가독성이 좋아짐자원이 하나인 경우 try-finally 절도 괜찮아 보이지만 자원이 두 개 이상이 되어 try-finally 절이 중첩이 되는 순간부터 가독성이 급격하게 안 좋아집니다. 단일 자원 다중 자원 다중 자원 코드를 보고 혹여나 아래와 같이 코드를 작성하면 단일 try-finally 절로 작성이 되지 않을까?라고 생각할 수 있겠지만 이렇게 작성할 경우 finally 절 내 ..

JAVA/Effective Java 2024.01.24

[아이템 8] finalizer와 cleaner 사용을 피하라

Java 8까지는 finalizer를 사용하여 자원을 정리했으며, Java 9부터는 cleaner가 도입되어 자원을 적절한 타이밍에 정리할 수 있도록 제공되었습니다. 기본적으로 Java에서는 객체가 더 이상 참조되지 않을 때 GC가 해당 객체를 수거하기 때문에 별도 처리를 안 해도 되는 케이스가 대부분이지만 파일이나 네트워크 리소스와 같은 외부 자원을 사용하는 객체의 경우, 해당 리소스를 명시적으로 해제해야 할 수 있습니다. 이를 위해 finalizer() 메서드와 cleaner가 기획되고 제공이 되었지만 아래에 열거할 이유들로 인해 이러한 메커니즘의 사용을 자제해야합니다. finalizer와 cleaner는 즉시 수행된다는 보장이 없음 finalizer와 cleaner는 실행되지 않을 수도 있음 fin..

JAVA/Effective Java 2024.01.23

[아이템 7] 다 쓴 객체 참조를 해제하라

객체 참조 해제는 기본적으로 GC가 해주지만 간혹 메모리 누수를 방지하기 위해 다 쓴 객체를 직접 참조 해제해야 하는 케이스가 있습니다. 책에서는 자기 메모리를 직접 관리하는 클래스의 경우 직접 참조를 해제해야 한다고 명시했고 대표적인 사례로 아래 세 가지 케이스를 예시로 들었습니다. Object 배열을 갖는 스택 캐시 리스너 혹은 콜백 1. Object 배열을 갖는 스택 아래 Stack 클래스와 같이 자기 메모리(Object 배열)를 직접 관리하는 케이스의 경우 객체 참조를 null로 할당하면서 직접 해제해야 합니다. 객체 참조를 null로 할당할 경우 GC가 돌 때 메모리를 회수할 수 있게 됩니다. 만약 pop() 메서드에서 위 코드와 같이 명시적으로 객체 참조를 해제하지 않고 아래와 같이 단순히 t..

JAVA/Effective Java 2024.01.22

[아이템 6] 불필요한 객체 생성을 피하라

저자는 아래의 세 가지 케이스에 대해서 불필요한 객체 생성을 피하라고 정리했습니다.문자열정규식 패턴오토 박싱 위 세 가지 케이스를 정리하기 전에 우선 하나를 명확히 짚고 가야 합니다. "아이템 6"의 제목만으로 객체 생성이 비싼 작업이라고 추측해서는 안 됩니다. 객체 생성 자체가 비싼 것은 아니기 때문에 위 세 가지 케이스를 제외하고는 얼마든지 객체를 생성해도 상관없습니다. 문자열JVM(Java Virtual Machine)은 내부적으로 문자열을 pool이라는 일종의 해시맵에 캐싱하고 다른 곳에서 동일한 문자열을 참조하려고 할 때 pool에서 꺼내 재사용하고 있습니다. 따라서 문자열은 굳이 new를 통해 동일한 문자열을 재생성하기보다는 문자열을 바로 할당하는 것이 메모리 측면에서 유리합니다. * 위 예제..

JAVA/Effective Java 2024.01.21

[아이템 5] 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라

사용하는 자원에 따라 동작이 달라지는 클래스는 앞서 다루었던 정적 유틸리티 클래스나 싱글턴 방식이 적합하지 않습니다. 이러한 클래스는 Spring Framework를 공부했다면 지겹게 들었을 의존성 주입(Dependency Injection)이 적합합니다. 사용하는 자원에 따라 동작이 달라지는 클래스 책에서 예시로 든 맞춤법 검사기는 사전에 의존하는데 한영사전이냐 영한사전이냐에 따라 SpellChecker 클래스의 동작이 달라질 것입니다. 한영사전은 isValid() 메서드를 통해 한글 단어가 존재하는지 확인할 것이고 suggestions() 메서드를 통해 오타가 났을 때 가장 근접한 한글 단어를 추천 반면 영한사전은 isValid() 메서드를 통해 영어 단어가 존재하는지 확인할 것이고 suggestio..

JAVA/Effective Java 2024.01.20

[아이템 4] 인스턴스화를 막으려거든 private 생성자를 사용하라

객체지향임에도 불구하고 간혹 인스턴스를 생성하지 말라고 권장하는 케이스가 있습니다. 보통 static 한 메서드들만 가지고 있는 유틸성 클래스가 위 케이스에 해당합니다. 인스턴스화를 막는 방법은 아래와 같이 두 가지가 있습니다. private 생성자를 통해 인스턴스화 방지 abstract 클래스로 생성하여 인스턴스화 방지 이 방법은 상속을 통해 우회적으로 생성자를 호출할 수 있으므로 불완전한 방법 방법 1. private 생성자를 통해 인스턴스화 방지 public 혹은 protected 생성자 없이 private 생성자만 정의할 경우 같은 클래스 내 main 함수에서 호출하지 않는 이상 생성자를 호출할 수 없어 인스턴스화를 방지할 수 있습니다. 같은 클래스 내 main 함수에서도 호출하는 것을 방지하고 ..

JAVA/Effective Java 2024.01.20

[아이템 3] private 생성자나 열거 타입으로 싱글턴임을 보증하라

싱글톤(singleton)이란? 아이템 3에 대해 논의하기에 앞서 우선 싱글톤 개념에 대한 이해가 선행되어야 합니다. 간단히 요약하자면 싱글톤 객체는 아래의 특성을 가집니다. 클래스의 인스턴스가 오직 1개만 생성되는 것을 보장하는 디자인 패턴 connection pool, thread pool, 디바이스 설정 객체의 경우 인스턴스를 여러 개 생성하면 자원을 낭비하거나 버그를 야기할 수 있으므로 오직 하나만 생성하고 해당 인스턴스를 사용하도록 하는 것이 목적 보다 자세한 내용은 제가 과거에 작성한 게시글 및 Jbee님이 작성한 글을 참고 바랍니다. https://jaimemin.tistory.com/1756 싱글톤(Singleton) 패턴 싱글톤 패턴 클래스의 인스턴스가 오직 1개만 생성되는 것을 보장하는..

JAVA/Effective Java 2024.01.19

[아이템 2] 생성자에 매개변수가 많다면 빌더를 고려하라

정적 팩토리 메서드와 생성자의 한계 및 해결책 정적 팩토리 메서드와 생성자 모두 optional 한 매개변수가 많을 때 적절히 대응하기 어렵다는 공통점이 있지만 점층적 생성자 패턴, Java Beans 패턴 혹은 Builder 패턴을 통해 어느 정도 대응이 가능합니다. 아래의 식품 영양정보를 예시로 각 패턴을 간략히 정리하겠습니다. 1회 내용량, 총 n회 내용량, 1회 제공량 당 칼로리와 같은 필수 항목(required field) 몇 개와 총 지방, 트랜스 지방, 포화 지방, 콜레스테롤, 나트륨 등 수많은 선택 항목(optional field)으로 이루어지고 대부분의 선택 항목들은 값이 0입니다. 점층적 생성자 패턴 점층적 생성자 패턴 적용 시 모든 필드를 전부 받는 생성자 혹은 정적 팩토리 메서드를 ..

JAVA/Effective Java 2024.01.18

[아이템 1] 생성자 대신 정적 팩토리 메서드를 고려하라

생성자 대신 정적 팩토리 메서드를 사용할 경우 얻을 수 있는 장단점은 아래와 같습니다. 장점 메서드명 즉 이름을 가질 수 있기 때문에 표현력이 높아짐 호출될 때마다 새로운 인스턴스를 생성하지 않아도 됨 반환 타입의 하위 타입 객체를 반환 가능 (인터페이스 기반 프레임워크) 입력 매개변수에 따라 매번 다른 클래스의 객체를 반환 가능 정적 팩토리 메서드를 작성하는 시점에는 반환할 객체의 클래스가 존재 여부를 고려하지 않아도 됨 단점 정적 팩토리 메서드만 제공할 경우 생성자를 private으로 선언하기 때문에 상속 불가능 역설적으로 이름을 가지기 때문에 생성자 대비 정적 팩토리 메서드 조회하기 번거로움 장점 1. 메서드명 즉 이름을 가질 수 있기 때문에 표현력이 높아짐 병원에 환자가 내원할 때 아래와 같이 두..

JAVA/Effective Java 2024.01.16