devseop08 님의 블로그

[API] System, Math, Number, Wrapper, BigInteger, BigDecimal 본문

Language/Java

[API] System, Math, Number, Wrapper, BigInteger, BigDecimal

devseop08 2025. 9. 16. 14:57

System

public final class System {  
    private static native void registerNatives();  
    static {  
        registerNatives();  
    }  

    private System() {  
    }  

    public static final InputStream in = null;  

    public static final PrintStream out = null;  

    public static final PrintStream err = null;  

    // Initial values of System.in and System.err, set in initPhase1().  
    private static @Stable InputStream initialIn;  
    private static @Stable PrintStream initialErr;  

    // indicates if a security manager is possible  
    private static final int NEVER = 1;  
    private static final int MAYBE = 2;  
    private static @Stable int allowSecurityManager;  

    // current security manager  
    @SuppressWarnings("removal")  
    private static volatile SecurityManager security;   
    // read by VM  
    // `sun.jnu.encoding` if it is not supported. Otherwise null.    
    // It is initialized in `initPhase1()` before any charset providers    
    // are initialized.    private static String notSupportedJnuEncoding;

기본 개요

  • 패키지: java.lang
  • 선언: public final class System
  • 특징:
    • final로 선언되어 상속 불가능
    • 생성자가 private이므로 인스턴스 생성 불가능
    • 모든 메서드와 필드는 static!
    • JVM 운영환경(standart input/output, properties, security, GC 등)을 다루는 중앙 유틸리티 클래스
    • System은 JVM 레벨에서 제공되는 전역 자원 접근 창구이다.

주요 정적 필드

  • System.in: 표준 입력 스트림(InputStream)
  • System.out: 표준 출력 스트림(PrintStream)
  • System.err: 표준 에러 출력 스트림(PrintStream)

주요 정적 메서드

  • 시간 관련
    • currentTimeMillis() : UTC 기준 현재 시각(밀리초 단위)
    • nanoTime() : 상대적 시간 측정용(나노초 단위, 벤치마크 등에서 사용)
  • 환경 변수 및 시스템 속성
    • getProperty(String key) : 시스템 속성 조회
      (예: "java.version", "os.name")
    • setProperty(String key, String value) : 속성 설정
    • getProperties() : 모든 속성 Properties 객체로 반환
    • getenv(String name) : 환경 변수 조회
    • getenv() : 모든 환경 변수 Map 반환
  • 입출력 스트림 관리
    • setIn(InputStream in)
    • setOut(PrintStream out)
    • setErr(PrintStream err)
      → 표준 입출력 스트림 교체 가능 (테스트 코드에서 자주 활용)
  • GC, 종료
    • gc() : GC 실행 요청
    • runFinalization() : 종료될 객체의 finalizer 실행 요청
    • exit(int status) : JVM 종료
    • halt(int status) : 강제 종료 (보안 관리자 무시)
  • 배열, 객체 관련
    • arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
      → 네이티브 메서드, 배열 복사
    • identityHashCode(Object x)
      hashCode() 오버라이딩 무시하고 원래 객체 해시코드 반환

내부 구현 특징

  • 네이티브 메서드 다수 포함: arraycopy, currentTimeMillis, nanoTime, identityHashCode, gc, mapLibraryName 등은 네이티브로 구현된다.
  • JVM 부트스트랩 과정에서 초기화: System 클래스는 VM 클래스와 협력하여 초기화 시점에 표준 스트림과 시스템 속성들을 설정한다.
  • 안전성: 보안 관리자가 활성화되어 있다면, 특정 메서드 호출(exit, setSecurityManager 등)은 SecurityException 발생 가능하다.

설계 관점

  • System은 사실상 싱글톤 패턴(전역 접근점)의 극단적인 형태 : 인스턴스 없음, 모든 기능이 static
  • final + private 생성자 -> 불변적이며 확장 불가
  • 유틸리티 클래스이자, JVM과 OS 레벨의 브릿지 클래스예시 코드
public class SystemExample {
    public static void main(String[] args) {
        // 시간
        long now = System.currentTimeMillis();
        System.out.println("현재 시간(ms): " + now);

        // 환경 변수
        String path = System.getenv("PATH");
        System.out.println("PATH 환경변수: " + path);

        // 시스템 속성
        String javaVersion = System.getProperty("java.version");
        System.out.println("Java 버전: " + javaVersion);

        // 배열 복사
        int[] src = {1, 2, 3, 4, 5};
        int[] dest = new int[5];
        System.arraycopy(src, 0, dest, 0, src.length);
        System.out.println("복사된 배열: " + java.util.Arrays.toString(dest));

        // 종료 (status 0은 정상 종료)
        // System.exit(0);
    }
}
  • System 클래스는 불변적이며 상태가 없는 final 유틸리티 클래스
  • JVM과 OS 자원(시간, 환경 변수, 속성, 표준 입출력, GC, 종료 등)을 관리하는 전역 접근 API

Math

public final class Math {  

    private Math() {}  

    public static final double E = 2.718281828459045;  

    public static final double PI = 3.141592653589793;  

    public static final double TAU = 2.0 * PI;  

    private static final double DEGREES_TO_RADIANS = 0.017453292519943295;  

    private static final double RADIANS_TO_DEGREES = 57.29577951308232;

기본 개요

  • 패키지: java.lang
  • 선언: public final class Math
  • 특징:
    • final 클래스 -> 상속 불가
    • 생성자가 private -> 인스턴스 생성 불가
    • 모든 메서드와 필드는 static
    • 수학 연산(삼각함수, 지수, 로그, 제곱근, 반올림, 난수 생성 등)을 위한 유틸리티 클래스
    • Math는 순수 함수 집합처럼 쓰이는 클래스이다.

주요 필드

  • public static final double E = 2.718281828459045; // 자연로그 밑
  • public static final double PI = 3.141592653589793; // 원주율

주요 메서드 분류

  1. 절대값, 부호 관련
    • abs(int a), abs(long a), abs(float a), abs(double a)
    • signum(double a), signum(float a) → 양수/음수/0 구분
  2. 올림/내림/반올림
    • ceil(double a) : 올림
    • floor(double a) : 내림
    • round(double a) : 반올림 → long 반환
    • rint(double a) : 가장 가까운 정수(double)
  3. 최대/최소
    • max(x, y), min(x, y) (int, long, float, double 오버로드)
  4. 제곱, 제곱근, 거듭제곱
    • pow(double a, double b)
    • sqrt(double a)
    • cbrt(double a) : 세제곱근
    • hypot(double x, double y) : √(x² + y²)
  5. 로그, 지수
    • exp(double a) : e^a
    • log(double a) : 자연로그
    • log10(double a) : log10
    • expm1(double a) : e^a - 1
    • log1p(double a) : log(1+a)
  6. 삼각함수
    • sin, cos, tan
    • asin, acos, atan
    • atan2(y, x)
  7. 기타
    • random() : 0.0 이상 1.0 미만의 난수 반환 (내부적으로 Random 사용)
    • toRadians(double angdeg)
    • toDegrees(double angrad)

내부 구현 특징

  • 네이티브 메서드 포함:
    많은 메서드(sin, cos, sqrt, log, exp, …)가 StrictMath 또는 OS 네이티브 라이브러리를 호출함.
  • 성능 최적화:
    JIT 컴파일러가 핫스팟 메서드(abs, max, min, pow 등)를 인라이닝하여 성능을 높임.
  • StrictMath와의 관계:
    • StrictMath는 항상 동일한 결과(플랫폼 독립적 보장)
    • Math는 성능 최적화를 위해 하드웨어/FPU/OS 라이브러리 함수를 사용할 수 있음

설계적 의미

  • Math는 상태 없는 불변 유틸리티 클래스
  • 사실상 싱글턴 패턴의 극단 형태(인스턴스 없음, 확장 불가, 전역 접근만 가능)
  • 난수 생성(random())만 내부적으로 상태(Random 인스턴스)를 갖고 변하기도 하지만 그 상태는 Math 클래스 외부에 노출되지 않는다. -> 불변성을 유지한다.

불변성

  • Math는 인스턴스를 만들 수 없고 상태도 없으며 모든 메서드가 static이므로 사실상 불변적이다.
  • 엄밀한 의미의 "불변 클래스"라기 보다는 상태 없는 final 유틸리티 클래스로 보는 것이 맞다.

정리

  • Mathfinal + private 생성자로 만들어진 순수 유틸리티 클래스
  • 모든 메서드가 static -> 인스턴스가 필요없다.
  • 수학 상수와 연산을 효율적이고 빠르게 제공
  • 불변성 개념을 충족하며 성격 상 immutable utility class로 보는 것이 맞다.

Number

public abstract class Number implements java.io.Serializable {
    public Number() {super();}

    public abstract int intValue();

    public abstract long longValue();

    public abstract float floatValue();

    public abstract double doubleValue();

    public byte byteValue() {  
        return (byte)intValue();  
    }

    public short shortValue() {  
        return (short)intValue();  
    }

    @java.io.Serial  
    private static final long serialVersionUID = -8742448824652078965L;
}

기본 개요

  • 패키지: java.lang
  • 선언: public abstract class Number implements java.io.Serializable
  • 특징:
    • abstract 클래스 -> 직접 인스턴스화 불가능
    • 여러 숫자 타입 클래스(Byte, Short, Integer, Long, Float, Double, BigInteger, BigDecimal 등)의 추상 부모 클래스
    • 직렬화 가능(Serializable

주요 메서드

  1. 추상 메서드 => 하위 클래스에서 구현 필요
    • int intValue()
    • long longValue()
    • float floatValue()
    • `double doubleValue()
  2. 일반 메서드 => 기본 구현 제공
  • byte byteValue() -> intValue 결과를 byte로 캐스팅
  • short shortValue() -> intValue 결과를 short로 캐스팅

설계적 의미

  • Number 클래스는 타입 계층의 다형성을 보장하는 뼈대이다. -> List<Number>에는 Integer, Double, BigDecimal을 다 저장할 수 있다.
  • 그러나 제네릭스와 오토박싱/언박싱이 등장하면서, 실무에서 직접 Number를 다루는 경우는 적고, 보통 Integer, Double 같은 구체 클래스나 Number를 상속받은 특수 타입을 사용한다.
  • 불변성:
    • JDK 기본 래퍼 클래스는 모두 불변 클래스
    • 따라서 Number의 하위 클래스도 불변성을 갖도록 하는 것이 일반적

정리

  • Number는 추상 클래스이자 숫자 계열 타입의 공통 조상
  • 여섯 가지 기본 변환 메서드를 정의(intValue, longValue, floatValue, doubleValue, byteValue, shortValue)
  • 실체 클래스(Integer, Double, BigDecimal 등)는 이를 구현
  • Number의 설계 목적은 다형성 확보 + 타입 변환 공통 API 제공
  • 실제 코딩에서는 Number 자체보다는 구체 래퍼 클래스들을 직접 사용하는 경우가 많다.

Wrapper 클래스

  • 자바는 기본 타입(byte, char, short, int, long, double, boolean)의 값을 갖는 객체를 생성할 수 있는데 이런 객체를 포장 객체, 즉 Wrapper 객체라고 한다.
  • 8개의 기본형을 객체로 다뤄야할 때 사용하는 클래스이다.
  • 포장 객체(Wrapper 객체)의 특징은 객체가 포장하고 있는 기본 타입의 값은 외부에서 변경할 수 없다는 점이다.
  • 만약 내부의 값을 변경하고 싶다면 새로운 포장 객체를 만들어야 한다.
  • 즉, Wrapper 객체는 불변 객체라는 것이다.
  • Wrapper 클래스는 모두 java.lang 패키지에 속한다.
기본형 래퍼 클래스
byte Byte
char Character
short Short
int Integer
long Long
float Float
double Double
boolean Boolean

박싱과 언박싱

  • 기본 타입의 값을 포장 객체로 만드는 과정을 박싱(boxing)이라 한다.
  • 반대로 포장 객체에서 기본 타입의 값을 얻어내는 과정을 언박싱(unboxing)이라고 한다.
  • 래퍼 클래스의 생성자로 박싱: 매개값으로 기본 타입의 값 또는 문자열을 전달
기본 타입의 값을 전달 문자열을 전달
Byte obj = new Byte(10); Byte obj = new Byte("10");
Character obj = new Character('가'); 없음
Short obj = new Short(100); Short obj = new Short("100");
Integer obj = new Integer(1000); Integer obj = new Integer("1000");
Long obj = new Long(10000); Long obj = new Long("10000");
Float obj = new Float(2.5F); Float obj = new Float("2.5F");
Double obj = new Double(3.5); Double obj = new Double("3.5");
Boolean obj = new Boolean(true); Boolean obj = new Boolean("true");
  • 생성자가 아닌 정적 메서드 valueOf 로 박싱
// Integer.java
public static Integer valueOf(int i) {  
    if (i >= IntegerCache.low && i <= IntegerCache.high)  
        return IntegerCache.cache[i + (-IntegerCache.low)];  
    return new Integer(i);  
}
Integer obj = Integer.valueOf(1000);
Integer obj = Integer.valueOf("1000");
  • 기본 타입 + Value() 메서드로 언박싱: 기본 타입의 값 얻어내기
기본 타입의 값을 이용
byte num = obj.byteValue();
char ch = obj.charValue();
short num = obj.shortValue();
int num = obj.intValue();
long num = obj.longValue();
float num = obj.floatValue();
double num = obj.floatValue();
boolean bool = obj.booleanValue();
public class BoxingUnBoxingExample {
    public static void main(String[] args) {
        // 박싱
        Integer obj1 = new Integer(100);
        Integer obj2 = new Integer("200");
        Integer obj3 = Integer.valueOf("300");

        // 언박싱
        int value1 = obj1.intValue();
        int value2 = obj2.intValue();
        int value3 = obj3.intValue();

        System.out.println(value1); // 100
        System.out.println(value2); // 200
        System.out.println(value3); // 300 
    }
}

자동 박싱과 자동 언박싱

  • 래퍼 클래스 타입에 기본 타입의 값이 대입될 경우에 자동 박싱
  • 자동 박싱은 컴파일 시 래퍼의 valueOf(...) 정적 메서드 호출로 변환된다.
Integer obj = 100; // 자동 박싱 -> 컴파일 타임에 Integer.valueOf(100)으로 변환
// Integer.java
public static Integer valueOf(int i) {  
    if (i >= IntegerCache.low && i <= IntegerCache.high)  
        return IntegerCache.cache[i + (-IntegerCache.low)];  
    return new Integer(i);  
}
  • 자동 언박싱은 인스턴스의 xxxValue() 메서드 호출로 변환된다.
  • 기본 타입의 변수에 래퍼 객체가 대입되는 경우에 자동 언박싱
Integer obj = new Integer(200); // 박싱
int value = obj; // 자동 언박싱 -> 컴파일 타임에 obj.intValue()로 변환
  • 기본 타입의 값에 래퍼 객체가 연산되는 경우에도 자동 언박싱
Integer obj = new Integer(300); // 박싱
int value = obj + 100; // + 연산 시 자동 언박싱 -> 컴파일 타임에 obj.intValue()로 변환

문자열을 기본 타입 값으로 변환

  • 래퍼 클래스는 문자열을 기본 타입의 값으로 변환할 때에도 많이 사용한다.
  • parse+기본 타입 이름 형식의 정적 메서드는 문자열을 매개값으로 전달받아 기본 타입의 값으로 변환
기본 타입의 값으로 변환
byte num = Byte.parseByte("10");
short num = Short.parseShort("100");
int num = Integer.parseInt("1000");
long num = Long.paseLong("10000");
float num = Float.parseFloat("2.5F");
double num = Double.parseDouble("3.5");
boolean bool = Boolean.parseBoolean("true');

포장값 비교: 박싱된 값 비교

  • 포장 객체는 내부의 값을 비교하기 위해 == 와 != 연산자를 사용하지 않는 것이 좋다.
  • == 와 != 연산자는 내부의 값을 비교하는 것이 아니라 포장 객체의 참조를 비교하기 때문이다.
Integer obj1 = 300; // 자동 박싱 -> 컴파일 타임에 Integer.valueOf(300)으로 변환
Integer obj2 = 300; // 자동 박싱 -> 컴파일 타임에 Integer.valueOf(300)으로 변환
System.out.println(obj1 == obj2); // false
  • 다만 래퍼 클래스 별로 valueOf 메서드를 이용하여 기본 타입 값을 박싱하는 경우 특정 범위의 기본 타입 값은 캐싱되기 때문에 valueOf 메서드를 이용하여 박싱한 기본 타입 값이 그 특정 범위 안의 값이라면 == 와 != 연산자로 내부의 값을 바로 비교할 수 있다.
  • 언제 캐시가 쓰이나?
    • 정적 팩토리: Integer.valueOf(int) 직접 호출 -> 캐시 적용
    • 문자열 변환: Integer.valueOf("42") -> 내부적으로 parseIntvalueOf(int) 호출 -> 캐시 적용
    • 생성자: new Integer(42)는 항상 새 객체 생성 => 캐시 미사용
// Integer.java
public static Integer valueOf(int i) {  
    if (i >= IntegerCache.low && i <= IntegerCache.high)  
        return IntegerCache.cache[i + (-IntegerCache.low)];  
    return new Integer(i);  
}

private static final class IntegerCache {  
    static final int low = -128;  
    static final int high;  

    @Stable  
    static final Integer[] cache;  
    static Integer[] archivedCache;  

    static {  
        // high value may be configured by property  
        int h = 127;  
        String integerCacheHighPropValue =  
            VM.getSavedProperty("java.lang.Integer.IntegerCache.high");  
        if (integerCacheHighPropValue != null) {  
            try {  
                h = Math.max(parseInt(integerCacheHighPropValue), 127);  
                // Maximum array size is Integer.MAX_VALUE  
                h = Math.min(h, Integer.MAX_VALUE - (-low) -1);  
            } catch( NumberFormatException nfe) {  
                // If the property cannot be parsed into an int, ignore it.  
            }  
        }  
        high = h;  

        // Load IntegerCache.archivedCache from archive, if possible  
        CDS.initializeFromArchive(IntegerCache.class);  
        int size = (high - low) + 1;  

        // Use the archived cache if it exists and is large enough  
        if (archivedCache == null || size > archivedCache.length) {  
            Integer[] c = new Integer[size];  
            int j = low;  
            for(int i = 0; i < c.length; i++) {  
                c[i] = new Integer(j++);  
            }  
            archivedCache = c;  
        }  
        cache = archivedCache;  
        // range [-128, 127] must be interned (JLS7 5.1.7)  
        assert IntegerCache.high >= 127;  
    }  

    private IntegerCache() {}  
}
  • 그 외의 경우에는 언박싱한 값을 비교해야 하며 포장 객체에 정확히 어떤 값이 저장될 지 모르는 상황이라면 == 와 != 연산자는 사용하지 않고 직접 내부 값을 언박싱해서 비교하거나 equals 메서드를 이용해서 내부 값을 비교하는 것이 좋다.
  • 기본 타입 별 캐싱되는 값의 범위: Float/Double은 캐싱 미사용
  • Integer 클래스 캐싱 범위 튜닝
    • 확장 가능: JVM 시작 시 시스템 프로퍼티로 Djava.lang.Integer.IntegerCache.high=<값>을 전달하면 상한을 127 이상으로 넓힐 수 있다.
    • 하한 -128은 고정
    • 캐시는 클래스 초기화 시 배열 한 번 만들어 채워두며 스레드 안전
래퍼 클래스 캐싱되는 값의 범위
Boolean true, false
Character \u0000\u007f(0127)
Byte, Short, Integer, Long -128 ~ 127
  • equals 메서드: 내부의 값을 비교하도록 재정의되어 있다.
// Integer.java
public boolean equals(Object obj) {  
    if (obj instanceof Integer) {  
        return value == ((Integer)obj).intValue();  
    }  
    return false;  
}
  • hashCode 메서드
// Integer.java
public int hashCode() {  
    return Integer.hashCode(value);  
}

public static int hashCode(int value) {  
    return value;  
}
public class ValueCompareExample {
    public static void main(String[] args) {
        System.out.println("[-128~127 초과값일 경우]");
        Integer obj1 = 300;
        Integer obj2 = 300;
        System.out.println("==결과: " + (obj1==obj2)); // false
        System.out.println("언박싱 후 ==결과: " 
                                    + (obj1.intValue()==obj2.intValue()); // true
        System.out.println("equals() 결과: " 
                                    + (obj1.equals(obj2))); // true

        System.out.println();

        System.out.println("[-128~127 범위값일 경우]");
        Integer obj1 = 10;
        Integer obj2 = 10;
        System.out.println("==결과: " + (obj1==obj2)); // true
        System.out.println("언박싱 후 ==결과: " 
                                    + (obj1.intValue()==obj2.intValue()); // true
        System.out.println("equals() 결과: " 
                                    + (obj1.equals(obj2))); // true
    }
}

BigInteger와 BigDecimal

공통점

  • 패키지 : java.math
  • 특징:
    • final 클래스 -> 상속 불가
    • immutable(불변 객체) -> 값이 변하지 않는다. 새로운 연산 결과는 항상 새 인스턴스 반환
    • Serializable, Comparable 인터페이스 구현
    • 정밀한 수치 연산 지원 (정수/실수)
    • Number 클래스의 하위 클래스 -> intValue(), longValue(), doubleValue() 등 변환 메서드 제공
    • 둘 다 기본 타입으로는 다룰 수 없는 큰 수치나 정밀도를 다룰 때 사용된다.

BigInteger

  1. 개요
    • 임의 정밀도의 정수 표현 클래스
    • int, long 범위를 넘어서는 정수도 표현 가능(메모리가 허용하는 한 무한대 크기 지원)
  2. 생성 방법
BigInteger big1 = new BigInteger("12345678901234567890");
BigInteger big2 = BigInteger.valueOf(42L);
  1. 주요 메서드
    • 사칙연산: add, subtract, multiply, divide, remainder
    • 거듭제곱: pow(int exponent)
    • 최대공약수: gcd(BigInteger val)
    • 소수 관련: isProbablePrime(int certainty), nextProbablePrime()
    • 비트 연산: and, or, xor, shiftLeft, shiftRight
  2. 예시
BigInteger a = new BigInteger("12345678901234567890");
BigInteger b = new BigInteger("98765432109876543210");
BigInteger sum = a.add(b);
System.out.println("합: " + sum); 

BigDecimal

  1. 개요
    • 임의 정밀도의 소수(부동소수점) 표현 클래스
    • float, double 은 부동소수점 오차 문제가 있지만, BigDecimal 은 오차 없이 정밀한 계산 가능
    • 금융, 과학 계산 등 정밀도가 중요한 연산에 필수
  2. 생성 방법: new BigDecimal(double) 사용 시 부동소수점 표현 오류가 그대로 반영되므로 문자열 생성자 권장
BigDecimal d1 = new BigDecimal("0.1"); // 문자열 권장(double 생성자 X)
BigDecimal d2 = BigDecimal.valueOf(0.1); // 내부적으로는 String 변환
  1. 주요 메서드
    • 사칙연산: add, subtract, multiply, divide
      • divide 시 반드시 RoundingMode 지정 필요 (ROUND_HALF_UP, RoundingMode.HALF_EVEN 등)
    • 스케일(scale): 소수점 자릿수 조정
      • setScale(int newScale, RoundingMode roundingMode)
    • 비교: compareTo(BigDecimal val) (equals()는 scale까지 비교 → 1.01.00equals로는 false)
  2. 예시
BigDecimal x = new BigDecimal("1.0");
BigDecimal y = new BigDecimal("0.9");
BigDecimal z = x.subtract(y);
System.out.println("결과: " + z); // 0.1 (정확)

BigInteger vs BigDecimal

구분 BigInteger BigDecimal
표현 정수 소수(부동소수점)
범위 메모리 제한까지 무한 메모리 제한까지 무한
불변성 ✅ (불변 객체) ✅ (불변 객체)
연산 사칙연산, 거듭제곱, GCD, 소수 판별, 비트 연산 사칙연산, 스케일 조정, 반올림 모드
주요 용도 암호학, 해시, 큰 수 계산 금융, 과학 계산, 정밀 소수 연산
equals() 값만 비교 값 + scale 비교 (1.01.00)
성능 단순 정수 연산이라 BigDecimal보다 빠름 소수점 처리 포함이라 BigInteger보다 느림

BigIntegerBigDecimalwrapper class(래퍼 클래스) 가 아니다.

  1. Wrapper Class(래퍼 클래스)란?
    • 기본 타입(primitive type) 을 객체로 감싸는 클래스
    • java.lang 패키지에 존재
    • boolean → Boolean, byte → Byte, short → Short,
      int → Integer, long → Long, float → Float, double → Double, char → Character
    • 특징:
      • 모두 final + immutable
      • 오토박싱/언박싱 지원 (JDK 1.5 이후)
        즉, 래퍼 클래스는 기본형 타입을 OOP 세계에서 쓸 수 있게 해주는 클래스
  2. BigInteger / BigDecimal 의 위치
    • 패키지: java.math
    • 공통점: Number 추상 클래스 상속, Serializable, Comparable 구현
    • 차이점: 기본 타입을 감싸는 클래스가 아님
      • BigInteger → 임의 정밀도 정수 표현 (기본형 intlong 을 감싸는 게 아님)
      • BigDecimal → 임의 정밀도 소수 표현 (기본형 float, double 을 감싸는 게 아님)
        즉, 별도의 수치 연산을 위한 "고정밀 수치 클래스"이지, primitive type을 감싸는 래퍼는 아니다**
구분 Wrapper Class BigInteger / BigDecimal
예시 Integer, Double, Boolean BigInteger, BigDecimal
패키지 java.lang java.math
대상 primitive type 감싸기 임의 정밀도 수치 표현
역할 기본형 → 객체화, 오토박싱/언박싱 지원 매우 큰 수 / 소수 정밀 계산
불변성
Number 상속

Number, Wrapper, BigInteger, BigDecimal 상속 구조

Object
 ├─ Boolean
 ├─ Character
 └─ Number(추상 클래스)
     ├─ Byte
     ├─ Short
     ├─ Integer
     ├─ Long
     ├─ Float
     ├─ Double
     ├─ BigInteger
     └─ BigDecimal