Effective Java 7 | Method

공부의 기록·2021년 12월 14일
0

Java (Effective Java)

목록 보기
8/12
post-thumbnail

Method

본 문서는 2021년 12월 23일 에 기록되었다.

Java : Class 중 Method Overloading 와 Java 전반에 대해서 알고있다고 전제하고 내용을 풀어나갈 예정이다. 또한 여기서는 Overloading 과 관련한 것을 메서드 시그니처 라고 부른다.


아이템 51 | 신중한 메서드 설계

원제목 | 메서드 시그니처를 신중히 설계하라

다음은 메서드와 관련된 일반적인 내용들이다.

  1. 메서드 이름을 신중히 짓자
  2. 편의 메서드를 너무 많이 만들지 말자
  3. 매개변수 목록은 짧게 유지하자 (4개 이하)

3번 매개변수의 목록을 줄이는 방법은 다음과 같다.

  1. 여러 메서드로 쪼갠다.
  2. 도우미 클래스를 만든다. Effective Java 중 아이템 24 | private 정적 멤버 클래스
  3. 빌더 패턴을 메서드 호출에 응용한다. Effective Java 중 아이템 2 | 빌더패턴

또한 매개변수의 타입은 다음을 준수하자.

  1. 4개 이하로 유지하자
  2. 매개변수의 타입으로는 클래스보다 인터페이스가 낫다
  3. 매개변수의 타입으로 가변인자는 조심스럽게 사용하자.
  4. boolean 보다는 ENUM 을 사용하자. (만약 그 값의 의미가 있다면)

아이템 52 | 신중한 다중정의 설계

원제목 | 다중정의는 신중히 사용하라

일단, 다중정의는 Overloading 에 대한 이야기를 하는 것입니다.
이러한 다중정의에서 주의할 점은 다음과 같습니다.

  1. 매개변수의 수가 동일한 다중정의를 기피하자
  2. 매개변수가 가변인자(... args) 라면 다중정의를 하지 말자
  3. 어쩔 수 없이 매개변수의 수가 동일하다면, 매개변수 명이 다른 다중정의도 고려하자

또한 jdk 1.5 에서 오토박싱 및 오토언박싱이 자동지원되기 시작했다.
따라서 해당 기능을 활용하여 만들어진 재밌는 것들이 많다.
이를 테면 Colleciton Framework 의 최상위 부모인 Collection 을 이용해서 주고받는다던가
아니면 int 와 String 을 받기 위해서 Object 를 이용해서 주고받는다던가 하는 것들이다.

하지만,
기본적으로 Primitive Type 보다 Wrapper Type, Object 등은 당연히 느릴 수밖에 없다.
따라서 편리함에 너무 취하지 않게 주의하는 것도 필요할 것 같다.
또한 매개변수의 범위가 너무 넓어지지도 않게 주의해야 한다.

그러나,
해당 다중정의의 원칙이 공식 API 에서도 안지켜지고 있는 것들이 많다.

예를들면,
String 클래스의 valueOf(char[]) 과 valueOf(Object) 는 전혀 다른 기능을 한다.

따라서 jdk 1.5 이후에서는 오토박싱과 오토언박싱 때문에 숫자가 동이한 다중정의 를 더욱 신중히 고려해야 한다는게 이번 아이템의 교훈 같다.


아이템 53 | 가변인수

가변인수는 명시 타입 의 인수를 0개 이상 받을 수 있다.
여기서는 다음과 같은 내용을 담고 있다.

  1. 가변인수 사용해보기
    1.a. 가변인수의 기본 활용 사례
    1.b. 매개변수 최소갯수 확보의 가변인수
  2. 가변인수 활용 사례는?

# 가변인수를 사용해보기

다음은 가변인수의 기본 활용 사례이다.
public static int sum(int... args) {
   int sum=0;
   for(int arg : args)
      sum+=arg;
   return sum;
}
가변인수에서 인수를 n 개 이상으로 활용하려면 다음과 같이 사용하면 된다.
public static int min(int firstArg, int... args){
   int min=firstArg;
   for (int arg:args) {
      if (arg<min) {
        min=arg;
      }
   }
   return min;
}

# 가변인수 활용 사례는?

System.out.printf 와 Reflection API 가 있다.


아이템 54 | 불변 객체, 불변 배열 반환

원제목 | null 이 아닌 빈 컬랙션이나 배열을 반환하라

방어적 코딩은 발생 가능한 여러 경우의 수에 대한 조치를 하는 것을 의미한다.
그 중 가장 많이 접하는 것들은 다음과 같다.

  1. NullPointerException
  2. OutOfBoundException
  3. NoSuchElementException

그 중에서 우리는 NullPointerException 을 일으키는 null 에 대한 고민을 해야 한다.
그 결과 우리는 값을 반환 받고 난 이후에 null 값인지를 확인하거나, Optional 등을 사용한다.
하지만 여기서 말할 불변 객체 및 불변 배열 을 사용하면 이러한 절차를 스킵할 수도 있다.
이 방법을 사용하는 곳은 Collection Framework 에서 static 한 공배열을 만들어두는 경우가 있다.

만약 User 라는 클래스가 있고 이 UserDao 를 통해 정보를 받아와서 리턴하는 메서드가 있다고 해보자.

public User {
  // 멤버변수
  // 생성자
  // 메서드
}
public UserDao {
  public User getUser() {
    // 프로세스
    if(조건문) {
       return new User("이름", "비밀번호", ... 등등);
    }
    return null
  }
}

이러한 경우는 null 값을 확인해야 한다.
물론 jdk 1.8 이후라면 Optional 이 있지만 이는 적절하지 않은 경우가 있다.

따라서 다음과 같이 정적 불변 객체, 정적 불변 배열 을 사용한다면 좋은 해결책이 될 수 있다.

public UserDao {
   public final static User EMPTY_USER=new User();
   // 값을 넣지 않고 일반 기본 생성자를 호출하면 null 로 가득채워진 텅빈 객체가 나온다.
   
   public User getUser() {
      if(조건문) {
         return new User("이름", "비밀번호", ... 등등);
      }
      return EMPTY_USER;
   }
}

이 방법은 배열에도 동일하게 사용할 수 있다.
다만 배열은 길이가 0 인배열은 자연스럽게 불변 배열 이 되므로 만들어두고 사용하면 된다.


아이템 55 | Optional 반환 주의

jdk 1.8 의 가장 큰 변화 중 하나는 Optional 이었다.
Optiona<T> 는 null 이 아닌 T 타입 참조를 하거나, 혹은 아무것도 담지 않을 수 있었다.
이 기능은 특정 조건에서 값을 반환할 수 없을 때 null 관련된 이슈에서 어느정도 자유롭기 때문에 혁신이라고 부르는 글도 본 적 있었다.

그렇다면 jdk 1.8 이전에는 어떻게 처리했어야 할까?

  1. return null
  2. throw Exception

위 방법은 모두 문제가 있었다
일단 null 을 리턴하면 한참 후에 NullPointerException 을 발생시켜 이를 추적하기 힘들다.
또한 Exception 을 생성하면 스택 추적 전체를 캡처하므로 비용도 만만치 않다.

물론, 아이템 54 | 불변 객체, 불변 배열 반환 에서 return null 의 대안을 말한 적이 있다.

하지만 다음과 같은 의문을 던져볼 수 있을 것 같다.

  1. 모든 경우에 이 방법을 사용할 수 있을까?
  2. Boolean, String, Integer 등 대응되는 모든 타입의 정적 불변 객체를 생성하는 것이 옳을까?
  3. Collection, Set, List 등은 어떻게 할까?

이후 Optional 과 Collection 등에 대한 주의사항은 Optional 을 별도로 배운 이후에 이어서 하도록 하겠다.


아이템 56 | /** */ 문서화 주석 사용

공개된 API 문서에는 문서화 주석을 사용하라
이는 현 시점에 중요하지 않은 것 같아서 넘어가도록 하였다.

profile
블로그 이전 : https://inblog.ai/unchaptered

0개의 댓글