9osari.log
← 목록으로

[JAVA] 래퍼, Class 클래스

2025년 5월 10일 · #java#김영한-java-중급

기본형의 한계와 래퍼 클래스

기본형의 한계

자바는 객체 지향 언어이지만 int, double 같은 기본형(Primitive Type) 은 객체가 아니라 객체 지향의 장점을 온전히 사용할 수 없다.

기본형의 한계를 이해하기 위해, 두 값을 비교해서 다음과 같은 결과를 출력하는 간단한 코드를 작성해보자

public static void main(String[] args) {
   int value = 10;
   int i1 = compareTo(value, 5);
   int i2 = compareTo(value, 10);
   int i3 = compareTo(value, 20);
   System.out.println("i1 = " + i1);
   System.out.println("i2 = " + i2);
   System.out.println("i3 = " + i3);
}
public static int compareTo(int value, int target) {
   if (value < target) {
     return -1;
   } else if (value > target) {
     return 1;
   } else {
     return 0;
   }
}
 
 //실행결과
i1 = 1
i2 = 0
i3 = -1

주요 한계점

직접 만든 래퍼 클래스

기본형 int를 감싸는 MyInteger 클래스 정의

public class MyInteger {
    private final int value;
    public MyInteger(int value) { this.value = value; }

    public int getValue() { return value; }

    public int compareTo(int target) {
        if (value < target) return -1;
        else if (value > target) return 1;
        else return 0;
    }

    @Override
    public String toString() {
        return String.valueOf(value);
    }
}
MyInteger myInteger = new MyInteger(10);
System.out.println(myInteger.compareTo(5)); // 1

기본형은 null을 사용 불가

// 기본형의 문제점: -1은 실제 값인지, 없는 값인지 모호함
private static int findValue(int[] intArr, int target) {
    for (int value : intArr) {
        if (value == target) return value;
    }
    return -1;
}

-1은 값이기도 하고 “없음”이기도 함 → 명확하지 않음

객체는 null을 사용 가능!

// 래퍼 클래스를 이용해 '값 없음'을 null로 명확히 구분 가능
private static MyInteger findValue(MyInteger[] intArr, int target) {
    for (MyInteger myInteger : intArr) {
        if (myInteger.getValue() == target) return myInteger;
    }
    return null;
}

//실행결과
-1
0
1
null

자바 래퍼 클래스

래퍼 클래스란?

기본형래퍼 클래스
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
charCharacter
booleanBoolean
Integer newInteger = new Integer(10); // 미래에 삭제 예정, 대신에 valueOf() 사
Integer integerObj = Integer.valueOf(10); // 추천 방식
Long longObj = Long.valueOf(100);
Double doubleObj = Double.valueOf(10.5);

System.out.println("newInteger = " + newInteger);
System.out.println("integerObj = " + integerObj);
System.out.println("longObj = " + longObj);
System.out.println("doubleObj = " + doubleObj);

System.out.println("내부 값 읽기");
int intValue = integerObj.intValue();
System.out.println("intValue = " + intValue);
long longValue = longObj.longValue();
System.out.println("longObj = " + longValue);

System.out.println("비교");
System.out.println("==: " + (newInteger == integerObj));
System.out.println("equals: " + newInteger.equals(integerObj));

//실행 결과
newInteger = 10
integerObj = 10
longObj = 100
doubleObj = 10.5
내부 값 읽기
intValue = 10
longObj = 100
비교
==: false
equals: true

박싱(Boxing) & 언박싱(Unboxing)

오토 박싱 / 오토 언박싱

int value = 7;
Integer boxed = value; // 오토 박싱
int unboxed = boxed;   // 오토 언박싱

→ 컴파일러가 Integer.valueOf(), intValue() 호출 코드를 자동으로 추가함

Integer i1 = Integer.valueOf(10);//숫자, 래퍼 객체 반환
Integer i2 = Integer.valueOf("10");//문자열, 래퍼 객체 반환
int intValue = Integer.parseInt("10");//문자열 전용, 기본형 반환
//비교
int compareResult = i1.compareTo(20);
System.out.println("compareResult = " + compareResult);
//산술 연산
System.out.println("sum: " + Integer.sum(10, 20)); //30
System.out.println("min: " + Integer.min(10, 20)); //10
System.out.println("max: " + Integer.max(10, 20)); //20

//실행결과
compareResult = -1
sum: 30
min: 10
max: 20

성능 비교

// 기본형 long
long sumPrimitive = 0;
for (int i = 0; i < 1_000_000_000; i++) {
    sumPrimitive += i;
}

// 래퍼 클래스 Long (오토 박싱 발생)
Long sumWrapper = 0L;
for (int i = 0; i < 1_000_000_000; i++) {
    sumWrapper += i;
}

실행 시간 예시 (M2 맥 기준)

왜 차이가 날까?

언제 어떤 걸 써야 하나?

상황추천 방식
성능 민감한 반복 연산기본형 (int, long 등)
유지보수가 중요한 일반 로직래퍼 클래스
컬렉션, 제네릭 사용 필요 시래퍼 클래스
값이 “없음(null)“을 표현래퍼 클래스

최근에는 컴퓨터 성능이 워낙 좋아졌기 때문에, 성능보다는 유지보수성과 가독성 을 우선으로 코드를 작성하는 경우가 많다.

최적화는 실제로 성능 문제가 발생했을 때, 그 핵심 병목 구간만 타겟팅해서 수행하는 것이 더 효과적이다.

자바 유틸리티 클래스 정리


Class 클래스

클래스의 정보(메타데이터)를 다루는데 사용한다. Class 클래스를 통해 개발자는 실행중인 자바 어플리케이션 내부의 필요한 클래스의 속성과 메서드에 대한 정보를 조회하고 조작할 수 있다.

주요 기능

Class 객체 얻는 방법 3가지

Class clazz = String.class; //클래스에서 조회

Class clazz = new String().getClass(); //인스턴스에서 조회

Class clazz = Class.forName("java.lang.String"); //문자열로 조회

주요 메서드

Field[] fields = clazz.getDeclaredFields(); //클래스의 모든 필드 조회
Method[] methods = clazz.getDeclaredMethods(); //클래스의 모든 메서드 조회
Class<?> superclass = clazz.getSuperclass(); //클래스의 부모 클래스 조회
Class<?>[] interfaces = clazz.getInterfaces(); //클래스의 인터페이스 조회 
//Class 조회
Class clazz = String.class; // 1.클래스에서 조회
//Class clazz = new String().getClass();// 2.인스턴스에서 조회
//Class clazz = Class.forName("java.lang.String"); // 3.문자열로 조회

// 모든 필드 출력
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
System.out.println("Field: " + field.getType() + " " +
field.getName());
}

// 모든 메서드 출력
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
System.out.println("Method: " + method);
}

// 상위 클래스 정보 출력
System.out.println("Superclass: " + clazz.getSuperclass().getName());

// 인터페이스 정보 출력
Class[] interfaces = clazz.getInterfaces();
for (Class i : interfaces) {
System.out.println("Interface: " + i.getName());
}

System 클래스 - 시스템 제어 및 정보 조회

주요 기능

System.out.println(System.currentTimeMillis());
System.arraycopy(original, 0, copied, 0, original.length);

Math 클래스

자주 쓰는 메서드

System.out.println(Math.round(2.5)); // 3
System.out.println(Math.random());   // 0.0 ~ 1.0

Random 클래스

Random random = new Random();        // 매번 다른 결과
Random fixed = new Random(1);        // 항상 같은 결과 (seed 고정)

int i = random.nextInt();            // 전체 범위
int i2 = random.nextInt(10);         // 0 ~ 9
int i3 = random.nextInt(10) + 1;     // 1 ~ 10
double d = random.nextDouble();      // 0.0 ~ 1.0
boolean b = random.nextBoolean();    // true/false

자바의 유틸리티 클래스들은 복잡한 시스템 작업을 간단한 코드로 가능하게 해준다. 필요한 기능이 있다면, 먼저 JDK의 유틸 클래스부터 찾아보는 습관을 들이자.


출처: [김영한의 실전 자바 - 중급 1편](https://www.inflearn.com/course/김영한의-실전-자바-중급-1)
···
← PREV [JAVA] String 클래스 NEXT → [JAVA] ENUM - 열거형