본문 바로가기
기타/이펙티브 자바

[이펙티브자바] 8.메서드

by 창이2 2022. 8. 6.

1. 매개변수가 유요한지 검사하라.

 1.1. 메서드 몸체가 수행되기 전에 매개변수를 검사하라.(assert, requireNonNull 등 사용)

 

2. 적시에 방어적 복사본을 만들어라.

 2.1. 외부에서 수정가능하지 못하게 방어적 코드를 작성하라.

더보기
import java.io.IOException;
import java.util.Date;

class Main {

    public static void main(String[] args) throws IOException {
        Date start = new Date();
        Date end = new Date();
        Period period = new Period(start, end);
        end.setYear(78); // period의 내부를 수정
        System.out.println(period.getEnd().getYear());
    }
    
}

final class Period {
    private final Date start;
    private final Date end;

    public Period(Date start, Date end){
        if(start.compareTo(end) > 0){
            throw new IllegalArgumentException("end가 start보다 빠를 수 없습니다.");
        }
        //깊은 복사를 통해 외부의 setYear와 같은 변경을 막아버리기
        this.start = start;// -> new Date(start.getTime())
        this.end = end;// -> new Date(end.getTime())
    }
    public Date getStart(){
        return start;
    }

    public Date getEnd(){
        return end;
    }
}

 

3. 메서드 시그니처를 신중히 설계하라.

 3.1. 메서드 이름을 신중히 짓자

 3.2. 편의메서드를 너무 많이 만들지 말자

 3.3. 매개 변수 목록은 짧게 유지하자, 매개 변수가 많을 경우

  3.3.1. 여러 메서드로 나누어서 실행

  3.3.2. 헬퍼클래스를 이용하여 여러 매개변수를 담기

  3.3.3. 위 두 방법 혼합하기

 

4. 다중정의는 신중히 사용하라

 4.1. 재정의한 메서드는 동적으로 선택되고 다중정의한 메서드는 정적으로 선택된다.

더보기
import java.io.IOException;
import java.util.*;

class Main {

    public static String classify(Set<?> set) {
        return "집합";
    }

    public static String classify(List<?> list) {
        return "리스트";
    }

    public static String classify(Collection<?> collection) {
        return "그 외";
    }

    public static void main(String[] args) throws IOException {
        //다중정의에 의한 실행
        Collection<?>[] collections = {
                new HashSet<String>(),
                new ArrayList<String>(),
                new HashMap<String, String>().values()
        };
        //이를 해결하려면 classify(Collection<?> collection)에서 타입체크를 이용해 처리
        for (Collection<?> collection : collections) {
            System.out.println(classify(collection));
        }

        ArrayList<Wine> wineList = new ArrayList();
        wineList.add(new Wine());
        wineList.add(new SparklingWine());
        wineList.add(new Champagne());

        for (Wine wine : wineList) {
            System.out.println(wine.name());
        }

    }

}

class Wine {
    String name() {
        return "포도주";
    }
}

class SparklingWine extends Wine {
    @Override String name() {
        return "스파클링 포도주";
    }
}

class Champagne extends Wine {
    @Override String name() {
        return "샴페인";
    }
}

 

5. 가변 인수는 신중히 사용하라

 

6. null 이 아닌 빈 컬렉션이나 배열을 반환하라.

 6.1. null을 반환하는 API는 사용하기 복잡해지고 오류 처리 코드도 늘어난다. 빈 배열이나 컬렉션을 매번 생성하기 보단 불변객체로 만들어 반환해라.

 

7. 옵셔널 반환은 신중히 하라.

 7.1. 메서드가 특정 조건에 값을 반환할수 없을때 예외 또는 Null을 던졌는데 예외 처리에 대한 비용과 Null에 대한 처리의 비용이 있기 때문에 옵셔널을 고려해 봐야한다.

 7.2. 옵셔널은 결과 없음이라는 의미를 명시하기 위해 존재하기 때문에 Null 반환을 하면 안된다. 

 7.3. 옵셔널은 타입 T 또는 빈 결과를 반환할 수 있다. 

 7.4. 옵셔널은 반환값이 없을 수 도 있음을 명시하기 위해 사용된다.

댓글