자바는 객체 지향 언어로 대부분의 데이터가 객체의 특성을 가지지만, int
와 double
과 같은 기본형 타입(Primitive Type)은 객체가 아니기 때문에 몇 가지 단점이 존재한다.
객체 특성 사용 불가
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
메서드를 정의해야 한다.
외부 메서드를 정의하여 문제를 해결할 수는 있지만, 이로 인해 다음과 같은 문제가 발생한다:
내부 처리 불가
객체지향의 일관성 부족
기본형 타입의 이러한 제한은 객체지향 프로그래밍에서 불편함을 초래할 수 있다. 이를 해결하기 위해 자바는 래퍼 클래스(Wrapper Class)를 도입하여, 기본형을 객체처럼 다룰 수 있도록 지원한다.
자바는 기본형에 대응하는 래퍼 클래스를 기본으로 제공한다.
자바의 기본형을 감싸는 Wrapper Class는 각 기본형의 첫 글자를 대문자로 대체하여 제공된다. 예를 들어, int
의 Wrapper Class는 Integer
이며, 이를 통해 숫자를 객체처럼 다룰 수 있다.
자바 기본 클래스
Integer
클래스는 두 수를 비교하는 compareTo
메서드를 제공한다.불변 객체(Immutable Object)
동등성 비교 시 equals()
사용
equals()
메서드를 사용해야 한다. ==
는 객체의 참조값을 비교하므로, 값 비교 시 사용하지 않는 것이 원칙이다.Wrapper Class는 기본형을 객체처럼 활용할 수 있게 하며, 추가적인 유용한 메서드와 함께 불변성을 제공한다. 이를 통해 기본형의 한계를 극복하고, 객체 지향 설계에 더 적합한 방식으로 데이터를 처리할 수 있다.
기본형을 래퍼로 바꾸는 것을 Boxing
이라고 한다. Wrapper는 다른 클래스처럼 이용할 수 있으나 특수한 표현으로 대신하기도 한다.
Integer int1 = new Integer(5); // 삭제될 예정
Integer int2 = Integer.valueOf(5); // 자바는 이 표현을 권장중
첫 번째 표현은 new
키워드를 사용하여 직접 객체를 생성하는 방식이다. 이는 자바에서 곧 삭제될 예정이라고 하지만, 언제 완전히 사라질지는 불확실하며 오랫동안 사용 가능할 가능성이 크다.
두 번째 표현은 Integer.valueOf()
메서드를 사용하는 방식으로, 자바에서 권장되는 표현이다. 두 표현 모두 같은 결과를 반환하지만, 내부 처리 방식이 다르다.
new Integer(5)
Integer.valueOf(5)
Integer.valueOf()
는 성능과 메모리 효율성을 고려한 자바의 권장 방식이다. new Integer()
는 불필요한 객체 생성을 유발하므로 사용을 지양해야 하며, 자바의 미래 버전에서 삭제될 가능성이 크다.
Boxing의 반대로, 만약 Integer객체를 기본형으로 바꾸기 위해서는 메서드 intValue()를 활용해서 Unboxing이 가능하다.
실제 현업에서 자바 유저들은 기본형과 래퍼의 서로간의 이동이 매우 잦았다. 이에 자바는 서로간의 이동에 대해 문법을 더 간편하게 만들어주었다.
Integer value1 = 7; // 래퍼 타입 만들기
int value2 = value1; // 기본형으로 바꾸기
조금 헷갈릴 수 있지만 처음 선언하는 type에 종속성을 가진다고 생각하면 편할 듯 하다. Integer로 선언했다면 =
뒤에 int가 오든 Integer가 오든 Integer가 되는 것이다. 역 또한 동일하다.
이전 자바의 참조형 vs 기본형에 대해 잘 학습했다면, 래퍼 클래스가 결국 객체이고 불변이라는 특성을 가지고 있다는 점을 알 수 있다.
하지만 래퍼 클래스를 사용하여 수많은 연산을 수행하면, 매번 새로운 객체가 생성되기 때문에 속도가 느려질 수 있다. 또한, 래퍼 클래스는 추가적인 객체 메타데이터를 포함하고 있어, 기본형에 비해 더 많은 메모리를 소비하게 된다.
따라서, 래퍼 클래스를 사용할 때는 메모리와 성능 측면에서 주의가 필요하며, 필요한 경우 기본형을 직접 사용하는 것이 더 효율적일 수 있다.
일반적으로 현재는 이정도의 최적화까지 고려 할 경우는 많지 않다. 만약 래퍼의 특성을 너무 이용하지 않아 래퍼의 사용이 남용된다고 여겨 최적화를 위해 기본형으로 수정해서 설계할 경우 객체지향적 설계에서 멀어질 수 있다. 특수한 경우가 아니라면 래퍼를 이용하는 것이 유지보수면에서 좋다.
유지보수 vs 최적화
코드 변경 없이 성능 최적화를 하면 가장 좋겠지만, 성능 최적화는 대부분 단순함보다는 복잡함을 요구한다. 최적화를 위해 유지보수해야할 코드가 늘어난다. 하지만 이러한 최적화가 시스템의 속도향상에 거의 무체감적으로 기여하지 못할 정도라면 불필요하다. 유지보수성과 최적화는 보통 trade-off 관계에 있으므로 개발자가 이 부분을 테스트 등을 통해 잘 개선해야한다.
자바의 Class 클래스(Class Class.. 이름이 참 헷갈린다.) Class 클래스의 주요 기능은 다음과 같다.
시스템과 관련된 기본기능 제공
이외의 Math, Random 클래스들이 있다. 사용하는 방법은 간단하니 어떤 기능들을 주는지만 잘 기억해서 찾아서 쓰도록 하자.