엄범

 

아이템 49. 매개변수가 유효한지 검사하라
  • 매개변수 유효한지 체크하는건 당연한 얘기이고...
  • null 처리 시 ``java if (null)`` 보다는 ``java Objects.requireNonNull()``이 낫고, 그 보다는 ``java Optional<>``이 낫다.
  • 자바의 `` assert``는 -ea 플래그를 주지 않으면 런타임에 아무런 효과도 없다. 쓸거면 플래그를 줘서 실행해야 한다.
    • assert는 `` private`` 메서드에서는 사용해도 좋다...고 하는데
    • 이말은 즉, 파라미터 체크는 public 메서드에서 다 끝내고 private 메서드에 넘기는 값들은 항상 조건을 만족하는 값이어야 한다는 얘기. 이므로 바깥에서 체크하고 assert로 또 체크 할 바에 그냥 바깥에서만 하는게 나은 것 같다.
    • 테스트 코드에서는 assert를 자주 쓰게 되긴 함. 프로덕션에서는 글쎄 잘 안쓰게 되는 듯

 

*** null 체크

```java

// null일 경우 NPE 발생이 필요할 때

this.something = Objects.requireNonNull(something);

Optional.ofNullable(User).map(User::getUserId).orElse(null)

```

 

아이템 50. 적시에 방어적 복사본을 만들라
  • getter 등에서 리턴해줄 때 객체 레퍼런스를 넘기면 외부에서 이 레퍼런스를 통해 객체 내부 값을 변경할 수 있으므로, copy본을 리턴하라는 얘기

 

아이템 51. 메서드 시그니처를 신중히 설계하라
  • 메서드 매개변수는 4개 이하가 좋다.
  • 매개변수가 너무 길 때 사용할 수 있는 방법 세가지?
    • 여러 메서드로 쪼갠다. 이 때 직교성이 높은 방향으로 쪼갠다.(중복 기능이 없도록 쪼갠다)
    • 매개변수를 여러 개 묶어서 넘길 수 있게 DataClass를 만든다. (static nested class로 둔다.)
    • DataClass를 큰 단위로 묶어서 정의하고, 빌더 패턴을 사용해 값을 세팅한다.
  • 참/거짓이 딱 맞는 상황이라면 boolean을, 그게 아니라면 원소 2개 짜리 enum 타입을 쓰는 것이 좋다

 

아이템 52. 다중정의(Overloading)는 신중히 사용하라
  • Overloading 메서드는 정적으로 선택된다.(정적 타입)
    • 즉, 객체를 넘길 때 그 객체의 실제 타입이 아니라 그 객체가 어떤 타입으로 넘어가는지를 보고 어떤 메서드가 호출될지 결정된다.
    • item52/CollectionClassifier.java  
    • 이 경우 그 객체의 실제 타입을 알아내려면 `` instanceof``를 쓰면 되긴 한다.
  • Override 메서드는 동적으로 선택된다.(동적 타입)
    • 즉, 객체를 넘길 때 그 객체의 실제 타입을 보고 어떤 메서드가 호출될지 결정된다.
    • item52/Overriding.java
  • 안전하게 가려면 매개변수 수가 같은 Overloading은 하지 않는게 좋다.
    • 위 예제에서 보다시피 형변환이 가능한 타입 끼리 Overloading이 되어 있는 경우 예상과 다르게 동작할 수 있다. 
    • 타입이 근본적으로 달라 이런 애매한 상황이 발생할 가능성이 없다면 Overloading도 괜찮다.

 

아이템 53. 가변인수는 신중히 사용하라

```java

// 이렇게 쓰면 0개 넣고 호출할 시 런타임에 실패하므로, 이렇게 쓰지말고

int min(int... args) 

 

// 이렇게 써야 0개 호출 시 컴파일 타임에 실패한다. 이걸 권장

int min(int firstArg, int... args) 

```

 

아이템 54. null이 아닌, 빈 컬렉션이나 배열을 반환하라
  • null 대신, ``java Collections.emptyList()`` 또는 ``java .toArray()``를 사용해 반환하라.

```java

// 컬렉션

return cheesesInStock.isEmpty() ? Collections.emptyList()

    : new ArrayList<>(cheesesInStock);

 

// 배열

return cheesesInStock.toArray(new Cheese[0]);

// toArray는 다음 표현을 메서드로 만든 것이다.

// return cheesesInStock.size() > 0 ? cheesesInStock 배열 : new Cheese[0]

```

 

아이템 55. 옵셔널 반환은 신중히 하라
  • Optional 똑바로 쓰기
  • ``java orElse(new User())``와 ``java orElseGet(User::new)``의 차이?
    • orElse는 거기까지 안와도 되는 상황이어도, 그 안에 있는 객체 User가 생성이 된다.
    • 반면 orElseGet은 람다를 넘기므로, 거기까지 도달하는 상황에만 코드가 실행되어 User가 생성된다.
    • 그래서 위와 같은 상황에서는 orElseGet을 쓰는 것이 좋고, 고정 문자열을 넘길 때는 ``java orElse("string")``을 쓰는 것이 좋다. 고정 문자열은 이미 생성되어 있는 문자열이므로.
  • 컬렉션, 스트림, 배열 등 컨테이너 타입은 옵셔널로 반환하지 말고 그냥 비어있는걸 반환하라.
  • 박싱된 옵셔널 대신 기본타입 옵셔널인 `` OptionalLong`` 등을 써라

 

아이템 56. 공개된 API 요소에는 항상 문서화 주석을 작성하라
  • 책 참고