본 문서는 2021년 12월 23일 에 기록되었다.
Java : Class 중 Method Overloading 와 Java 전반에 대해서 알고있다고 전제하고 내용을 풀어나갈 예정이다. 또한 여기서는 Overloading 과 관련한 것을 메서드 시그니처 라고 부른다.
원제목 | 메서드 시그니처를 신중히 설계하라
다음은 메서드와 관련된 일반적인 내용들이다.
3번 매개변수의 목록을 줄이는 방법은 다음과 같다.
또한 매개변수의 타입은 다음을 준수하자.
원제목 | 다중정의는 신중히 사용하라
일단, 다중정의는 Overloading 에 대한 이야기를 하는 것입니다.
이러한 다중정의에서 주의할 점은 다음과 같습니다.
또한 jdk 1.5 에서 오토박싱 및 오토언박싱이 자동지원되기 시작했다.
따라서 해당 기능을 활용하여 만들어진 재밌는 것들이 많다.
이를 테면 Colleciton Framework 의 최상위 부모인 Collection 을 이용해서 주고받는다던가
아니면 int 와 String 을 받기 위해서 Object 를 이용해서 주고받는다던가 하는 것들이다.
하지만,
기본적으로 Primitive Type 보다 Wrapper Type, Object 등은 당연히 느릴 수밖에 없다.
따라서 편리함에 너무 취하지 않게 주의하는 것도 필요할 것 같다.
또한 매개변수의 범위가 너무 넓어지지도 않게 주의해야 한다.
그러나,
해당 다중정의의 원칙이 공식 API 에서도 안지켜지고 있는 것들이 많다.
예를들면,
String 클래스의 valueOf(char[]) 과 valueOf(Object) 는 전혀 다른 기능을 한다.
따라서 jdk 1.5 이후에서는 오토박싱과 오토언박싱 때문에 숫자가 동이한 다중정의 를 더욱 신중히 고려해야 한다는게 이번 아이템의 교훈 같다.
가변인수는 명시 타입 의 인수를 0개 이상 받을 수 있다.
여기서는 다음과 같은 내용을 담고 있다.
public static int sum(int... args) {
int sum=0;
for(int arg : args)
sum+=arg;
return sum;
}
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 가 있다.
원제목 | null 이 아닌 빈 컬랙션이나 배열을 반환하라
방어적 코딩은 발생 가능한 여러 경우의 수에 대한 조치를 하는 것을 의미한다.
그 중 가장 많이 접하는 것들은 다음과 같다.
그 중에서 우리는 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 인배열은 자연스럽게 불변 배열 이 되므로 만들어두고 사용하면 된다.
jdk 1.8 의 가장 큰 변화 중 하나는 Optional 이었다.
Optiona<T> 는 null 이 아닌 T 타입 참조를 하거나, 혹은 아무것도 담지 않을 수 있었다.
이 기능은 특정 조건에서 값을 반환할 수 없을 때 null 관련된 이슈에서 어느정도 자유롭기 때문에 혁신이라고 부르는 글도 본 적 있었다.
그렇다면 jdk 1.8 이전에는 어떻게 처리했어야 할까?
위 방법은 모두 문제가 있었다
일단 null 을 리턴하면 한참 후에 NullPointerException 을 발생시켜 이를 추적하기 힘들다.
또한 Exception 을 생성하면 스택 추적 전체를 캡처하므로 비용도 만만치 않다.
물론, 아이템 54 | 불변 객체, 불변 배열 반환 에서 return null 의 대안을 말한 적이 있다.
하지만 다음과 같은 의문을 던져볼 수 있을 것 같다.
이후 Optional 과 Collection 등에 대한 주의사항은 Optional 을 별도로 배운 이후에 이어서 하도록 하겠다.
공개된 API 문서에는 문서화 주석을 사용하라
이는 현 시점에 중요하지 않은 것 같아서 넘어가도록 하였다.