Java 유용한 클래스 - 1, java.util.Objects 클래스
java.util 패키지는 많은 클래스가 있지만 실제로 자주 쓰는 것은 그렇게 많지 않기 때문에,
모든 클래스들을 설명하기 보다는 자주 사용되는 중요한 클래스들만을 골라서 활용해보자
java.util.Objects 클래스
Object 클래스의 보조 클래스로 Math 클래스처럼 모든 메서드가 static이다.
객체의 비교나 널 체크에 유용하다.
requireNonNull()은 해당 객체가 널이면 NullPointerException을 발생시킨다.
두 번째 매개변수로 지정하는 문자열은 예외의 메세지가 된다.
static <T> T requireNonNull(T obj)
static <T> T requireNonNull(T obj, String message)
static <T> T requireNonNull(T obj, Supplier<String> messageSupplier)
예전 같으면 매개변수의 유효성 검사를 다음과 같이 해야 하는데,
이제는 requireNonNull()의 호출만으로 간단히 끝낼 수 있다.
void setName(String name) {
if (name == null)
throw new NullPointerException("name must not be null.");
this.name = name;
}
>>
void setName(String name){
this.name = Objects.requireNonNull(name, "name must not be null.");
}
Object 클래스에는 두 객체의 등가비교를 위한 equals만 있고,
대소 비교를 위한 compare()가 없는 것이 아쉬워서,
Objects에는 compare가 추가되었다.
Object에 있는 equals가 Objects에도 있는 이유는 null검사를 하지 않아도 된다.
if (a != null && a.equals(b)) // a가 null인지 반드시 확인해야 함
if (Objects.equals(a, b)) // 매개변수 값이 null인지 확인할 필요 없음
객체를 재귀적으로 비교하기 때문에,
다차원 배열의 비교도 가능한 메서드인 deepEquals()도 있다.
두 2차원 배열을 비교할 때, 단순히 equals만으로는 할 수 없어서,
equals와 반복문을 함께 써야 하는데 deepEquals를 쓰면 간단히 끝난다.
String[][] str2D = new String[][]{{"aa", "bb"}, {"aa", "bb"}};
String[][] str2D2 = new String[][]{{"aa", "bb"}, {"aa", "bb"}};
sysout(Objects.equals(str2D, str2D2)); // false
sysout(Objects.deepEquals(str2D, str2D2)); // true
toString도 equals처럼 내부적으로 널 검사를 한다는 것 빼고는 특별한 것이 없다.
값이 널일 때, 대신할 값을 지정할 수도 있다.
static String toString(Object o)
static String toString(Object o, String nullDefault)
마지막으로 hashCode() 역시 내부적으로 널 검사를 한 후에 Object 클래스의 hashCode를 호출할 뿐이다.
단, 널일 때는 0 반환
보통은 클래스에 선언된 인스턴스의 변수들이 hashCode()를 조합해서 반환하도록 hashCode()를 오버라이딩 하는데,
그 대신 매개변수의 타입이 가변인자인 메서드를 사용하면 편하다.
static int hashCode(Object o)
static int hash(Object... values)
static import문을 사용했음에도 불구하고 Object 클래스의 메서드와 이름이 같은 것들은 충돌이 난다.
즉, 컴파일러가 구별을 못한다.
그럴 때는 클래스의 이름을 붙여줄 수밖에 없다.