[김영한의 실전 자바 중급편1] - Wrapper

jkky98·2024년 5월 15일
1

Java

목록 보기
16/51

기본형의 한계

자바는 객체 지향 언어로 대부분의 데이터가 객체의 특성을 가지지만, intdouble과 같은 기본형 타입(Primitive Type)은 객체가 아니기 때문에 몇 가지 단점이 존재한다.

기본형 타입의 단점

  1. 객체 특성 사용 불가

    • 객체는 유용한 메서드를 제공하거나 참조를 활용할 수 있지만, 기본형 타입은 이러한 특성을 사용할 수 없다.
    • 예를 들어, 기본형 타입은 컬렉션 프레임워크와 같은 객체 기반 기능을 사용할 수 없다.
  2. null을 가질 수 없음

    • 기본형 타입은 null을 가질 수 없으며, 초기화되지 않았을 경우 기본값을 가진다.
      예를 들어, int는 초기화되지 않으면 자동으로 0을 가진다.
    • 때로는 값이 "없음"이라는 상태를 나타내야 할 필요가 있지만, 기본형은 항상 값을 가지기 때문에 이를 표현하기 어려운 문제가 있다.

이러한 단점을 보완하기 위해 자바는 래퍼 클래스(Wrapper Class)를 제공하여 기본형을 객체로 감싸는 방식을 지원한다.

// 예시 1
// 메서드 활용불가 예시
int num1 = 5;
boolean result = num1.compareTo(5); // 불가능한 표현

// 예시 2
// 외부 메서드 필요
int num2 = 5;
boolean result = compareTo(num1, 5);

// compareTo 메서드 구현
public static boolean compareTo(int num1, int num2) {
    return Integer.compare(num1, num2) == 0;
}

예시 1의 두 번째 줄은 컴파일 에러를 발생시킨다. 이는 num1이 기본형 int 타입이기 때문에 내장 메서드라는 개념을 사용할 수 없기 때문이다.

compareTo는 두 수를 비교한 결과를 반환하는 메서드로, 기본형에 대해 사용하려면 외부에 별도로 compareTo 메서드를 정의해야 한다.

외부 메서드를 정의하여 문제를 해결할 수는 있지만, 이로 인해 다음과 같은 문제가 발생한다:

  1. 내부 처리 불가

    • 기본형은 객체가 아니기 때문에 메서드를 직접 제공하지 못한다.
    • 문제를 해결하기 위해 외부 메서드에 의존하게 되며, 이는 객체지향의 "내부적으로 데이터를 처리하고 행동을 정의한다"는 개념에서 벗어나게 된다.
  2. 객체지향의 일관성 부족

    • 기본형은 객체의 특성을 가지지 않아, 모든 처리를 외부적으로 수행해야 한다.
    • 이는 객체지향 설계의 원칙과 어긋나는 결과를 초래한다.

결론

기본형 타입의 이러한 제한은 객체지향 프로그래밍에서 불편함을 초래할 수 있다. 이를 해결하기 위해 자바는 래퍼 클래스(Wrapper Class)를 도입하여, 기본형을 객체처럼 다룰 수 있도록 지원한다.

Java Wrapper Class

자바는 기본형에 대응하는 래퍼 클래스를 기본으로 제공한다.

자바의 기본형을 감싸는 Wrapper Class는 각 기본형의 첫 글자를 대문자로 대체하여 제공된다. 예를 들어, int의 Wrapper Class는 Integer이며, 이를 통해 숫자를 객체처럼 다룰 수 있다.

Wrapper Class의 특징

  1. 자바 기본 클래스

    • Wrapper Class는 자바에서 기본적으로 제공되며, 자주 사용되는 유용한 메서드를 포함하고 있다.
    • 예를 들어, Integer 클래스는 두 수를 비교하는 compareTo 메서드를 제공한다.
  2. 불변 객체(Immutable Object)

    • Wrapper Class는 불변 객체로 설계되어 있어, 대부분의 메서드가 기존 객체를 변경하지 않고 새로운 객체를 반환한다.
  3. 동등성 비교 시 equals() 사용

    • 기본형을 참조형으로 변환한 것이기 때문에, 동등성 비교 시 반드시 equals() 메서드를 사용해야 한다.
    • 참조형에서 ==객체의 참조값을 비교하므로, 값 비교 시 사용하지 않는 것이 원칙이다.

결론

Wrapper Class는 기본형을 객체처럼 활용할 수 있게 하며, 추가적인 유용한 메서드와 함께 불변성을 제공한다. 이를 통해 기본형의 한계를 극복하고, 객체 지향 설계에 더 적합한 방식으로 데이터를 처리할 수 있다.

Boxing

기본형을 래퍼로 바꾸는 것을 Boxing이라고 한다. Wrapper는 다른 클래스처럼 이용할 수 있으나 특수한 표현으로 대신하기도 한다.

Integer int1 = new Integer(5); // 삭제될 예정
Integer int2 = Integer.valueOf(5); // 자바는 이 표현을 권장중

두 표현의 차이

첫 번째 표현은 new 키워드를 사용하여 직접 객체를 생성하는 방식이다. 이는 자바에서 곧 삭제될 예정이라고 하지만, 언제 완전히 사라질지는 불확실하며 오랫동안 사용 가능할 가능성이 크다.

두 번째 표현은 Integer.valueOf() 메서드를 사용하는 방식으로, 자바에서 권장되는 표현이다. 두 표현 모두 같은 결과를 반환하지만, 내부 처리 방식이 다르다.

내부 처리 방식

new Integer(5)

  • 매번 새로운 객체를 생성한다.
  • 동일한 값을 가진 객체를 여러 번 생성할 경우, 메모리 낭비가 발생할 수 있다.

Integer.valueOf(5)

  • 자바는 내부적으로 캐싱(caching)을 활용하여 -128부터 127 사이의 값은 이미 생성된 객체를 재사용한다.
  • 동일한 값을 가진 객체를 반복해서 생성하지 않으므로, 메모리와 성능 측면에서 더 효율적이다.

결론

Integer.valueOf()는 성능과 메모리 효율성을 고려한 자바의 권장 방식이다. new Integer()는 불필요한 객체 생성을 유발하므로 사용을 지양해야 하며, 자바의 미래 버전에서 삭제될 가능성이 크다.

Unboxing

Boxing의 반대로, 만약 Integer객체를 기본형으로 바꾸기 위해서는 메서드 intValue()를 활용해서 Unboxing이 가능하다.

Autoboxing

실제 현업에서 자바 유저들은 기본형과 래퍼의 서로간의 이동이 매우 잦았다. 이에 자바는 서로간의 이동에 대해 문법을 더 간편하게 만들어주었다.

Integer value1 = 7; // 래퍼 타입 만들기
int value2 = value1; // 기본형으로 바꾸기

조금 헷갈릴 수 있지만 처음 선언하는 type에 종속성을 가진다고 생각하면 편할 듯 하다. Integer로 선언했다면 = 뒤에 int가 오든 Integer가 오든 Integer가 되는 것이다. 역 또한 동일하다.

주요 method

  • valueOf : 래퍼타입을 반환한다.
  • parseInt : 문자열을 기본형으로 변환한다. 타입에 따라 parseXxx가 존재한다.
  • compareTo : 숫자크기 비교
  • sum, min, max ... : 연산 수행

래퍼의 단점

이전 자바의 참조형 vs 기본형에 대해 잘 학습했다면, 래퍼 클래스가 결국 객체이고 불변이라는 특성을 가지고 있다는 점을 알 수 있다.

하지만 래퍼 클래스를 사용하여 수많은 연산을 수행하면, 매번 새로운 객체가 생성되기 때문에 속도가 느려질 수 있다. 또한, 래퍼 클래스는 추가적인 객체 메타데이터를 포함하고 있어, 기본형에 비해 더 많은 메모리를 소비하게 된다.

따라서, 래퍼 클래스를 사용할 때는 메모리와 성능 측면에서 주의가 필요하며, 필요한 경우 기본형을 직접 사용하는 것이 더 효율적일 수 있다.

장단점을 구분해서 사용해야 할까?

일반적으로 현재는 이정도의 최적화까지 고려 할 경우는 많지 않다. 만약 래퍼의 특성을 너무 이용하지 않아 래퍼의 사용이 남용된다고 여겨 최적화를 위해 기본형으로 수정해서 설계할 경우 객체지향적 설계에서 멀어질 수 있다. 특수한 경우가 아니라면 래퍼를 이용하는 것이 유지보수면에서 좋다.

유지보수 vs 최적화

코드 변경 없이 성능 최적화를 하면 가장 좋겠지만, 성능 최적화는 대부분 단순함보다는 복잡함을 요구한다. 최적화를 위해 유지보수해야할 코드가 늘어난다. 하지만 이러한 최적화가 시스템의 속도향상에 거의 무체감적으로 기여하지 못할 정도라면 불필요하다. 유지보수성과 최적화는 보통 trade-off 관계에 있으므로 개발자가 이 부분을 테스트 등을 통해 잘 개선해야한다.

Class 클래스

자바의 Class 클래스(Class Class.. 이름이 참 헷갈린다.) Class 클래스의 주요 기능은 다음과 같다.

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

System 클래스

시스템과 관련된 기본기능 제공

  • 현재시간 제공 (밀리, 나노초)
  • 환경변수 읽기
  • 시스템 속성 읽기
  • 배열 고속 복사(시스템을 직접 사용하는 것이라 속도가 매우 빠름)
  • 시스템 종료(사용권장하지 않음)

이외의 Math, Random 클래스들이 있다. 사용하는 방법은 간단하니 어떤 기능들을 주는지만 잘 기억해서 찾아서 쓰도록 하자.

profile
자바집사의 거북이 수련법

0개의 댓글