java, 래퍼 클래스의(Long, Integer) 비교와 Number#longValue 메서드

숫자의 비교

  • 기본 타입(long, int 등)의 경우 객체가 아니므로 값을 비교하기 위한 메서드가 존재하지 않는다. == 를 사용하여 비교한다.
// primitive 비교
long p1 = 1L;
long p2 = 1L;

assertThat(p1==p2).isTrue();
// assertThat(p1.equals(p2)).isTrue(); // 컴파일 에러
// assertThat(p1.longValue()==p2.longValue()).isTrue(); // 컴파일 에러
  • 래퍼 클래스의 경우 -128에서 127까지는 == 비교가 가능하다.
  • constant pool 로 인해 발생한다. 자주 사용하는 값에 대해서는 미리 객체를 생성하고 해당 객체의 주소를 리턴하기 때문이다.
// constant pool 내부
Long c1 = 1L;
Long c2 = 1L;

assertThat(c1==c2).isTrue();
assertThat(c1.equals(c2)).isTrue();
assertThat(c1.longValue()==c2.longValue()).isTrue();
  • 해당 범위를 넘어설 경우 == 비교가 불가능하다.
// constant pool 외부
Long l1 = 1243234324L;
Long l2 = 1243234324L;

assertThat(l1==l2).isFalse();
assertThat(l1.equals(l2)).isTrue();
assertThat(l1.longValue()==l2.longValue()).isTrue();

equals보다 longValue를 선호한다

  • 다만 개인적으로 equals보다 longValue를 선호한다. 타입으로부터 좀 더 자유롭다.
Number i = (Number) 1;
Number l = (Number) 1L;

assertThat(i == l).isFalse();
assertThat(i.equals(l)).isFalse();  // equals가 더는 동작하지 않는다.
assertThat(i.longValue() == l.longValue()).isTrue();
private boolean compareIntegerAndLong(Number n1, Number n2) {
    return n1.longValue() == n2.longValue();
}
  • 정수를 비교함에 있어 우리는 정수 타입이 무엇인지 알 필요가 없다. 그러므로 longValue를 통한 비교가 범용성이 좋아 보인다.

참고 : https://www.baeldung.com/java-compare-long-values