숫자를 처리하는 클래스(Wrapper 클래스)

de_sj_awa·2021년 5월 2일
0
post-custom-banner

숫자를 처리하는 클래스(Wrapper 클래스)

자바에서 간단한 계산을 할 때에는 대부분 기본 자료형(Primitive Type)을 사용한다. 이 기본 자료형은 자바의 힙(Heap)이라는 영역에 저장되지 않고, 스택이라는 영역에 저장되어 관리된다. 따라서, 계산을 할 때 보다 빠른 처리가 가능하다.

그런데, 이러한 기본 자료형의 숫자를 객체로 처리해야 할 필요가 있을 수도 있다. 따라서, 자바에는 다음과 같이 기본 자료형으로 선언되어 있는 타입의 클래스들이 선언되어 있다.

  • Byte
  • Short
  • Integer
  • Long
  • Float
  • Double
  • Character
  • Boolean

Character 클래스를 제외하고 나머지 클래스들은 각 기본 자료형의 이름에서 첫 문자만 대문자로 바뀌었다고 보면 된다. 그런데, Character와 Boolean을 제외한 숫자를 처리하는 클래스들은 감싼 클래스(Wrapper) 클래스라고 불리며, 모두 Number라는 abstract 클래스를 확장(extends) 한다. 그리고 겉으로 보기에는 참조 자료형이지만, 기본 자료형처럼 사용할 수 있다. 왜나하면, 자바 컴파일러에서 자동으로 형 변환을 해주기 때문이다.

그리고 Character 클래스를 제외하고는 공통적인 메소드를 제공한다. 바로 parse타입이름() 메소드valueOf()라는 메소드다.

예제 코드

package lang;

public class JavaLangNumber {
    public static void main(String[] args){
        JavaLangNumber sample = new JavaLangNumber();
        sample.numberTypeCheck();
    }
    public void numberTypeCheck(){
        String value1 = "3";
        String value2 = "5";
        byte byte1 = Byte.parseByte(value1);
        byte byte2 = Byte.parseByte(value2);
        System.out.println(byte1 + byte2);

        Integer refInt1 = Integer.valueOf(value1);
        Integer refInt2 = Integer.valueOf(value2);
        System.out.println(refInt1 + refInt2 + "7");
    }
}

코드를 보면 알겠지만, 이 두 가지 메소드는 모두 static 메소드다. 따라서, 타입의 객체를 생성할 필요 없이 바로 사용할 수 있다. 둘 다 String과 같은 문자열을 숫자 타입으로 변환한다는 공통점이 있지만, parse타입() 메소드는 기본 자료형을 리턴하고, valueOf() 메소드는 참조 자료형을 리턴한다.

실행 결과

첫 번째 결과가 byte 타입을 더한 것이니까 8로 출력되는 것은 모두 쉽게 이해할 것이다. 그런데, 두 번째 결과가 87로 나온 것은 조금 이해하기 힘들 것이다. 왜냐하면, 참조 자료형은 두 값을 더할 수 없는데 숫자 연산이 된 8이라는 값이 출력되고, "7"이 그 뒤에 붙었기 때문이다.

참조 자료형 중에 더하기 연산이 가능한 것은 String 뿐이다. 그런데, 참조 자료형 중에서 Byte, Short, Integer, Long, Float, Double 타입들은 필요시 기본 자료형처럼 사용할 수 있다. 따라서 new를 사용하여 객체를 만들지 않아도 값을 할당할 수 있다. 즉, 다음과 같이 사용하는 것도 전혀 문제되지 않는다.

public void numberTypeCheck2() {
    Integer refInt1;
    refInt1 = 100;
    System.out.println(refInt.doubleValue());
}

컴파일도 이상 없이 되며, 실행도 잘 된다. 그렇다면, 왜 혼동되게 이러한 숫자를 처리하는 참조 자료형을 만들었을까? 그 이유는 다음과 같다.

  • 매개 변수를 참조 자료형으로만 받는 메소드를 처리하기 위해서
  • 제네릭과 같이 기본 자료형을 사용하지 않는 기능을 사용하기 위해서
  • MIN_VALUE(최소값)나 MAX_VALUE(최대값)와 같이 클래스에 선언된 상수 값을 사용하기 위해서
  • 문자열을 숫자로, 숫자를 문자열로 쉽게 변환하고 2, 8, 10, 16 진수 변환을 쉽게 처리하기 위해서

라고 생각할 수 있다.

기본 자료형을 참조 자료형으로 만든 클래스들은 Boolean 클래스들을 제외하고 모두 MIN_VALUE나 MAX_VALUE라는 상수를 갖고 있다. 해당 타입이 나타낼 수 있는 값의 범위를 확인하려면 static으로 선언되어 있는 이 상수들을 다음과 같이 사용하면 된다.

public void numberMinMaxCheck(){
        System.out.println("Byte min="+Byte.MIN_VALUE+" max="+Byte.MAX_VALUE);
        System.out.println("Short min="+Short.MIN_VALUE+" max="+Short.MAX_VALUE);
        System.out.println("Integer min="+Integer.MIN_VALUE+" max="+Integer.MAX_VALUE);
        System.out.println("Long min="+Long.MIN_VALUE+" max="+Long.MAX_VALUE);
        System.out.println("Float min="+Float.MIN_VALUE+" max="+Float.MAX_VALUE);
        System.out.println("Double min="+Double.MIN_VALUE+" max="+Float.MAX_VALUE);
        System.out.println("Character min="+(int)Character.MIN_VALUE+" max="+(int)Character.MAX_VALUE);
    }

마지막에 Character의 경우에는 그냥 출력할 경우 char 타입으로 출력되므로 알아보기 힘들다. 따라서 int 타입으로 변환하여 그 값을 확인하도록 해 놓았다.

실행 결과

Integer과 Long 타입을 읽기가 어렵다. 이 값을 2진수나 16진수로 표현해서 보면 조금 더 보기 편하다. 예를 들어 Integer의 최소값과 최대값을 2진수와 16진수로 나타낸 결과를 보려면, 다음과 같이 Integer 클래스에서 제공하는 toBinaryString()라는 메소드를 사용하면 된다.

 public void intergerMinMaxCheckBinary(){
        System.out.println("Integer BINARY min="+Integer.toBinaryString(Integer.MIN_VALUE));
        System.out.println("Integer BINARY max="+Integer.toBinaryString(Integer.MAX_VALUE));

        System.out.println("Integer HEX min="+Integer.toHexString(Integer.MIN_VALUE));
        System.out.println("Integer HEX max="+Integer.toHexString(Integer.MAX_VALUE));
    }

실행 결과

어떤 값을 원하는 진수의 숫자로 표현하고 싶을 때는 직접 구현하는 것보다는 이와 같이 숫자 클래스에서 제공되는 메소드를 사용하면 된다.

그러나 돈 계산과 같이 중요한 연산을 수행할 때, 정수형은 BigInteger, 소수형은 BigDecimal을 사용하여야 정확한 계산이 가능하다. 이 두 클래스는 모두 java.lang.Number 클래스의 상속을 받았으며, java.math 패키지에 선언되어 있다.

참고

  • 자바의 신
profile
이것저것 관심많은 개발자.
post-custom-banner

0개의 댓글