정적 팩터리와 생성자는 선택적 매개변수가 많을 때 적절히 대응하기가 어렵다는 점이 있다. 그럼 이런 선택적 매개변수가 많을 때 클래스는 어떤 식으로 대응을 할까? 점층적 생성자 패턴 사용 점층적 생성자 패턴은 필수 매개변수만 받는 생성자와 선택 매개변수를 받는 생성자 여러개를 모두 두어 클라이언트가 요구하는 사항에 따라 객체를 생성하는 패턴 방식이다. public class NutritionFacts { private final int servingSize; // (mL, 1회 제공량) 필수 private final int servings; // (회, 총 n회 제공량) 필수 private final int calories; // (1회 제공량당) 선택 private final int fat; // (g..
지난 포스팅 때, 책을 그저 적기만 한 것 같아 다시 한번 포스팅을 시작했다.. 생성자와 정적 팩터리 메서드 보통 클래스의 인스턴스는 public 생성자를 활용하여 생성한다. 그런데 클래스 자체는 생성자와 별도로 아래와 같은 정적 팩토리 메소드를 제공할 수 있다. public static int testMethod() { return 0; } 위에서 설명한 바와 같이 클래스에서는 클라이언트에게 public 생성자를 제공해주지만 이 뿐만 아니라 정적 팩토리 메소드도 제공해줄 수 있다. //public 생성자 public class MyBook { public MyBook() {} } //static factory method public class MyBook { private MyBook() {} pub..
equals를 재정의하려거든 hashCode도 재정의하라 equals를 재정의한 클래스 모두에서는 hashCode도 재정의해야한다. 만약, hashCode를 재정의하지 않을 시, HashMap이나 HashSet 같은 컬렉션의 원소로 사용할 때 문제를 일으킬 것이다. Object 명세에서 발췌한 규약을 살펴보자 Equals 비교에 사용되는 정보가 변경되지 않았다면, hashCode 메소드는 몇번을 호출해도 항상 같은 값을 반환해야 한다. 단, 애플리케이션이 다시 시작할 시에는 이 값이 달라져도 상관 없다. equals(Object)가 두 객체를 같다고 판단했다면, 두 객체의 hashCode는 똑같은 값을 반환해야 한다. equals(Object)가 두 객체르 다르다고 판단했더라도, 두 객체의 hashCod..
equals는 일반 규약을 지켜 재정의하라 Equals 메소드는 재정의하기 쉬워 보이지만 곳곳에 함정이 도사리고 있어 자칫하면 끔찍한 결과를 초래할 수 있다. 이런 이유로 인해 아예 재정의 안하는 것이 옳은 선택일 수 있다. 다음 상황에 맞닥드릴 시에는 재정의를 하지 않는 것이 좋다. 각 인스턴스가 본질적으로 고유하다. 값을 표현하는 게 아니라 동작하는 개체를 표현하는 클래스를 말한다. 인스턴스의 논리적 동일성을 검사할 일이 없다. 인스턴스의 논리적 동일성을 검사할 일이 없다면 Object의 기본 equals만으로 해결이 된다. 상위 클래스에서 재정의한 equals가 하위 클래스에도 딱 들어맞는다. Set구현체는 AbstractSet이 구현한 equals를 상속받아 사용하고, List 구현체들은 Abst..
명명 패턴보다 어노테이션을 사용하라 테스트 프레임워크인 JUnit은 버전 3까지 테스트 메서드 이름을 test로 시작하게끔 했다. 하지만 이런 명명패턴은 단점이 존재했다. 명명패턴의 단점 오타가 나면 안된다. 실수로 tsetSafetyOverride로 지으면 JUnit 3은 이 메소드를 무시하고 지나치기 때문에 해당 테스트가 통과했다고 오해할 수 있다. 올바른 프로그램 요소에서만 사용되리라 보증할 방법이 없다. 메서드가 아닌 클래스의 이름을 TestSafetyMechanisms으로 지어 JUnit에 던져줄 시 JUnit은 클래스의 이름에는 관심이 없어 무시해버린다. 그로 인해, 테스트를 하지 않고 지나치기 때문에 개발자는 이번에도 테스트가 통과했다고 오해할 수 있다. 프로그램 요소를 매개변수로 전달할 마..
@Override 어노테이션을 일관되게 사용하라 해당 어노테이션을 일관되게 사용하면 여러가지 악명 높은 버그들을 예방해준다. 다음 Bigram 프로그램을 살펴보자. Bigram은 영어 알파벳 2개로 구성된 문자열을 표현하는 소스다. pubcli class Bigram { private final char first; private final char second; public Bigram(char firtst, char second) { this.first = first; this.second = second; } public boolean equals(Bigram b) { return b.first == first && b.second = second; } public int hashCode() { r..
검사 예외와 런타임 예외 자바는 문제 상황을 알리는 타입(Throwable)으로 검사 예외, 런타임 예외, 에러 이렇게 세 가지를 제공한다. 하지만, 해당 타입을 언제 무엇을 사용해야하는 지 헷갈리는 경우가 있다. 그럼 이것들은 언제 무엇을 사용해야 하는가? 호출하는 쪽에서 복구하리라 여겨지는 상황이라면 검사 예외를 사용해라 검사 예외를 던지면 호출자가 그 예외를 catch로 잡아 처리하거나 더 바깥으로 전파하도록 강제하게 된다. 따라서, 메소드 선언에 포함된 검사 예외 각각은 그 메소드를 호출했을 때 발생할 수 있는 유력한 결과임을 API 사용자에게 알려주는 것이다. Ex. API 메소드 호출 시 강제적으로 try-catch 혹은 throw 를 해야하는 경우 비검사 throwable은 두 가지로, 런타..
예외는 진짜 예외 상황에만 사용하라 예외는 오직 예외 상황에서만 써야한다. 절대 일상적인 제어 흐름용으로 사용해선 안 된다. try { int i = 0; while(true) { range[i++].climb(); } } catch (ArrayIndexOutOfBoundsException e) { } 위 코드는 무한루프를 돌다가 배열의 끝에 도달하게 되면 ArrayIndexOutOfBoundsException 이 발생하면 끝을 내버리는 코드다. 왜 예외를 써서 루프를 종료한 거지? 세 가지 잘못된 추론을 살펴볼 수 있다. 예외를 통한 명확한 검사가 빠를 것이다. 코드를 try-catch 블록 안에 넣으면 JVM이 적용할 수 있는 최적화가 제한된다. JVM은 배열에 접근할 때마다 경계를 넘지않는지 매번 ..
- Total
- Today
- Yesterday
- effectivejava
- springboot
- 정적팩터리메서드
- 점층적 생성 패턴
- java
- 이펙티브 자바
- 자바8
- 스프링부트
- 연관관계
- 김영한
- mustache
- 팩토리 메소드 패턴
- Spring
- 빈 순환 참조
- try catch finally
- 이펙티브자바
- JPA
- 복사 팩토리
- 인프런
- package-private
- try with resources
- java8
- ifPresent
- junit
- 빌더 패턴
- Effective Java
- 생성자
- @Lazy
- flatMap
- jdk버전
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |