Java의 Primitive Type, Boxed Type과 한계
Java에서는 Primitive Type(원시 타입)과 Boxed Type(박스형 타입)의 변수를 구분해 코드를 작성하였다. Boxed Type은 Class로 원시 타입을 감싸는 형태로 만들어졌다.
Java Primitive Type | Java Boxed Type |
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
이는 초기에 매우 효과적이었는데, 원시 타입을 사용할 수 있는 곳에 원시 타입을 사용해 코드를 만들면 메모리가 많이 절약될 수 있었기 때문이다. 하지만 이는 시간이 지날수록 비효율적이어진다. 같은 목적을 위해 만들어졌으면서 두 가지 타입으로 나뉘는 것은 호환성 상 매우 비효율적이기 때문이다. 매번 변환하는 코드로 인해 많은 줄의 코드가 작성되었고, 다른 객체와 호환성 있게 사용하기 위해 객체를 필요로 하는 곳에서는 Boxed Type으로 만들어져야 했기 때문에 매우 비효율적이었다.
Kotlin은 Primitive Type, Boxed Type을 단일 타입으로 만들어 구분하지 않는다
이를 개선하여 Kotlin에서는 Primitive Type과 Boxed Type을 단일 타입으로 만들어 코드를 짤 시 구분하지 않도록 하였다. 예를 들어 int와 Integer은 Int로 통합해 정수 자료형을 표현하기 위해서는 Int만들 사용 하도록 하였다.
그렇다면 Kotlin은 원시 타입으로부터 얻을 수 있는 효율성을 모두 포기한 것일까? 아니다. Kotlin은 주로 JVM 기반으로 돌아가고 있기 때문에 컴파일 시 원시 타입으로 변환될 수 있으면 컴퓨터가 알아서 변환해 준다.
아래 Int class의 주석을 살펴보자.
/**
* Represents a 32-bit signed integer.
* On the JVM, non-nullable values of this type are represented as values of the primitive type `int`.
*/
public class Int private constructor() : Number(), Comparable<Int> {
주석에는 두가지가 명시되어 있다.
- 32bit signed Integer을 표현한다.
- JVM 위에서 Nullable Type이 아닌 Int는 Primitive Type인 int로 표현된다.
즉, Int, Long, Float 등이 사용되는 곳에서는 컴파일 시 원시 타입으로 변환할 수 있으면 자동으로 변환해 준다. 그리고 그 조건은 Non-Nullable 하나이다. 즉, Int?는 Primitive Type으로 변환되지 않지만, Int는 변환된다는 뜻이다. 사람이 직접 하는 것보다 컴퓨터가 하는 것이 안정성이 있어 이에 대한 최적화도 매우 잘 된다.
이를 통해 Kotlin은 원시 타입으로 얻을 수 있는 효율성과 호환성을 모두 잡을 수 있었다.
Kotlin에서는 명시적으로 Primitive Type Array를 만들 수 있다.
하지만 Kotlin에서도 Primitive Type Array에 대한 지원은 따로 한다. ByteArray, CharArray, ShortArray, IntArray, LongArray, FloatArray 등을 사용해 Java에서 byte[], char[], short[], int[], long[], float[] 등으로 만들었던 원시타입 Array를 만들 수 있도록 한다.
다만 Java와는 다르게 Kotlin에서는 이를 class로 표현하며, 컴파일시 Primitive Type Array로 변환해 준다는 점의 차이가 있다.
이를 확인하기 위해 IntArray의 주석을 살펴보자.
/**
* An array of ints. When targeting the JVM, instances of this class are represented as `int[]`.
* @constructor Creates a new array of the specified [size], with all elements initialized to zero.
*/
public class IntArray(size: Int) {
JVM을 대상으로 할 때, 이 클래스의 인스턴스는 int[]로 표현됩니다.
constructor을 사용해 [size] 크기의 새로운 배열을 생성할 수 있고, 모든 요소는 0으로 초기화됩니다.
위 주석에는 두가지 중요한 사항이 들어있다. 바로 이것이 컴파일될 수 int[]로 자동 변환된다는 점과 constructor을 사용하면 모두 0으로 초기화된 원시 Int 배열을 만들 수 있다는 점이다.
즉, Kotlin에서는 IntArray, ByteArray, CharArray, LongArray 등을 사용해 원시 타입의 Array를 만들 수 있다.
다음 글에서는 Primitive Type을 조작하는 간단한 방법에 대해 살펴보도록 한다.