Stay Hungry Stay Foolish

자바/자바 중급

[자바 중급] 04. Wrapper class

dev스카이 2024. 9. 30. 12:38

기본형의 한계

자바는 객체 지향 언어인데 int나 double같은 기본형은 객체가 아니기 때문에 다음과 같은 한계가 있다.

  • 객체가 아님 : 기본형 데이터는 객체가 아니기 때문에, 객체 지향 프로그래밍의 장점을 살릴 수 없다. 또한 기본형은 객체가 아니므로 메서드도 제공할 수 없다.
  • null 값을 가질 수 없음 : 기본형 데이터 타입은 null값을 가질 수 없다.

기본형의 한계를 해결하기 위해 도입된 것이 래퍼 클래스이다. 

 

Wrapper class(래퍼 클래스)

특정 기본형을 객체로 감싸서(Wrap) 만든 클래스를 래퍼 클래스라고 한다. 래퍼 클래스를 직접 만들 수도 있지만, 자바가 기본으로 제공해준다. 다음은 int 래퍼 클래스를 직접 만든 클래스이다.

 

 

직접 만든 래퍼 클래스

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); //숫자를 문자로 변경
    }
}

 

int value라는 단순한 기본형 변수를 하나 가지게 하고, 이 기본형 변수를 편리하게 사용하도록 다양한 메서드를 제공한다. compareTo() 메서드를 클래스 내부로 캡슐화했고, 이 클래스는 불변으로 설계했다. 다음은 자바가 제공하는 기본형에 대응하는 래퍼 클래스이다.

 

 

자바 래퍼 클래스

자바가 제공하는 기본 래퍼 클래스는 불변이라는 점과 equals로 비교해야한다는 특징이 있다.

  • byte → Byte
  • short → Short
  • int → Integer
  • long → Long
  • float → Float
  • double → Double
  • char → Character
  • boolean → Boolean

 

Autoboxing

박싱(Boxing)

기본형을 래퍼 클래스로 변경하는 것을 마치 박스에 물건을 넣은 것 같다해서 박싱이라 한다. 

 

언박싱(Unboxing)

반대로, 래퍼 클래스에 들어있는 기본형 값을 다시 꺼내는 것을 마치 박스에 들어있는 물건을 꺼내는 것 같다고 해서 언박싱이라 한다.

  • intValue()가 이에 해당하는 메서드이다.

 

자바는 개발자의 편의를 위해 자바 1.5부터 오토 박싱, 오토 언박싱을 지원하고 있다. 따라서 아래 코드와 같이 일일이 작성해줘야 하는 번거로움이 줄어들었다.

//Primitive -> Wrapper
Integer boxedValue = Integer.valueOf(value); 
//Wrapper -> Primitive
int unboxedValue = boxedValue.intValue();

 

아래의 코드는 오토 박싱과 오토 언박싱을 사용하여 위 코드를 개선한 것이다.

Integer boxedValue = value; //오토 박싱(Auto-boxing)
int unboxedValue = boxedValue; //오토 언박싱(Auto-Unboxing)

 

 

 

래퍼 클래스의 주요 메서드

  • valueOf() : 래퍼 타입을 반환한다. 숫자, 문자열을 모두 지원한다.
  • parseInt() : 문자열을 기본형으로 변환한다.
  • compareTo() : 내 값과 인수로 넘어온 값을 비교한다. 내 값이 크면 1 , 같으면 0 , 내 값이 작으면 -1 을 반환한다.
  • Integer.sum() , Integer.min() , Integer.max() : static 메서드이다. 간단한 덧셈, 작은 값, 큰 값 연산을 수행한다.

 

Class 클래스

자바에서 Class 클래스는 클래스의 정보(메타데이터)를 다루는데 사용된다. Class 클래스를 통해 개발자는 실행중인 자바 애플리케이션 내에서 필요한 클래스의 속성과 메서드에 대한 정보를 조회하고 조작할 수 있다. 다시 말하면, Class 클래스에는 클래스의 모든 정보가 들어있어 이 정보를 기반으로 인스턴스를 생성하거나, 메서드를 호출하고, 필드의 값도 변경할 수 있다. 다음은 Class 클래스의 주요 메서드 및 특징이다.

  • 타입 정보 얻기 : 클래스의 이름, 슈퍼클래스, 인터페이스, 접근 제한자 등과 같은 정보를 조회할 수 있다.
  • 리플렉션 : 클래스에 정의된 메서드, 필드, 생성자 등을 조회하고, 이들을 통해 객체 인스턴스를 생성하거나 메서드를 호출하는 등의 작업을 할 수 있다.
  • 동적 로딩과 생성 : Class.forName() 메서드를 사용하여 클래스를 동적으로 로드하고, newInstance() 메서드를 통해 새로운 인스턴스를 생성할 수 있다.
  • 애노테이션 처리 : 클래스에 적용된 애노테이션(annotation)을 조회하고 처리하는 기능을 제공한다.

 

조회 방법

  • 클래스에서 조회하는 방법 : Class clazz = String.class; 
  • 인스턴스에서 조회하는 방법 : Class clazz = new String().getClass();
  • 문자열로 조회하는 방법 : Class clazz = Class.forName("java.lang.String"); 

 

주요 메서드 및 기능

  • getDeclaredFields() : 클래스의 모든 필드를 조회한다.
  • getDeclaredMethods() : 클래스의 모든 메서드를 조회한다.
  • getSuperclass() : 클래스의 부모 클래스를 조회한다.
  • getInterfaces() : 클래스의 인터페이스들을 조회한다.
  • getDeclaredConstructor() : 생성자를 선택한다.
  • newInstance() : 선택된 생성자를 기반으로 인스턴스를 생성한다.

 

※ 주의

throws Exception : main() 옆에 throws Exception 코드를 붙여줘야 컴파일 오류가 발생하지 않는다.

 

 

System 클래스

System 클래스는 시스템과 관련된 기본 기능들을 제공한다. 다음은 주요 기능들이다.

  • 표준 입력, 출력, 오류 스트림 : System.in , System.out , System.err은 각각 표준 입력, 표준 출력, 표준 오류 스트림을 나타낸다.
  • 시간 측정 : System.currentTimeMillis()와 System.nanoTime() 은 현재 시간을 밀리초 또는 나노초 단위로 제공한다.
  • 환경 변수 : System.getenv() 메서드를 사용하여 OS에서 설정한 환경 변수의 값을 얻을 수 있다.
  • 시스템 속성 : System.getProperties()를 사용해 현재 시스템 속성을 얻거나 System.getProperty(String key)로 특정 속성을 얻을 수 있다. 시스템 속성은 자바에서 사용하는 설정값이다.
  • 시스템 종료 : System.exit(int status) 메서드는 프로그램을 종료하고, OS에 프로그램 종료의 상태 코드를 전달한다.
    • 상태 코드 0 : 정상 종료
    • 상태 코드 0 이 아님 : 오류나 예외적인 종료
  • 배열 고속 복사 : System.arraycopy는 시스템 레벨에서 최적화된 메모리 복사 연산을 사용한다. 직접 반복문을 사용해서 배열을 복사할 때 보다 수 배 이상 빠른 성능을 제공한다.

 

Math 클래스

Math 클래스는 수 많은 수학 문제를 해결해주는 클래스이다. 

 

Random 클래스

랜덤의 경우 Math.random()을 사용해도 되지만 Random 클래스를 사용하면 더욱 다양한 랜덤값을 구할 수 있다. 참고로 Math.random()도 내부에서는 Random 클래스를 사용한다. Random 클래스는 java.util 패키지 소속이다.

 

Seed

랜덤은 내부에서 씨드(Seed)값을 사용해서 랜덤 값을 구한다. 그런데 이 씨드 값이 같으면 항상 같은 결과를 출력한다.

Random random = new Random(1); //seed가 같으면 Random의 결과가 같다.