KotlinはJavaのプリミティブ型に当たるデータ型を持ちません。しかし、同等な記述が基本データ型を用いて出来ます。
Kotlinにおいて、基本データ型がどのように扱われているのか、まとめます。
※環境:Android Studio Giraffe | 2022.3.1 Patch 1
Kotlin 1.8.10
Kotlinの基本データ型
KotlinはJavaのプリミティブ型に当たるデータ型を持ちません。ただ、一対一に対応する基本データ型があります。Javaのラッパークラスに似ています。
両者を比べると表のようになります。
Java | Kotlin | |
---|---|---|
提供方法 | システム組み込み | ライブラリ |
扱われ方 (メモリーの格納方法) | 値のまま直接保持 ・符号なし整数 ・2の補数による整数 ・UTF-16 コード ・IEEE 754準拠の浮動小数点数 | オブジェクト ・プロパティを実装 ・関数を実装 |
データ型の種類 | byte short int long float double boolean char | Byte Short Int Long Float Double Boolean Char |
※Javaはオブジェクトを作るプリミティブ型のラッパークラスも存在する |
※基本データ型はStringも含まれますが、表はJavaのプリミティブ型に関連するデータ型へ限定しています。
基本データ型はオブジェクト
Kotlinの基本データ型はソースコードとバイトコードで振る舞いが異なります。
ソースコードレベルはオブジェクトです。しかし、バイトコードレベルはJavaのプリミティブ型です。
Kotlinコンパイラーが一対一に対応する基本データ型の仲立ちを行っています。
基本データ型の振る舞い
例えば、次のようなソースコードを考えます。整数22を定義して、+3を行うプログラムです。
var _value: Int = 22 _value += 3 Log.i(TAG, "value = ${_value}")
バイトコード
バイトコードは整数22を値のまま、PUSHやPOPを行ったり、+3の演算を行ったり、することが確認できます。
整数22は特定の(メモリ上の)格納先やその参照先を持ちません。すべての処理は、ローカル変数(レジスタ)やスタック(PUSH/POP先)など、VM(バーチャルマシン)の内部リソースで完結しています。
これはプリミティブ型の振る舞い方です。
L0 LINENUMBER 8 L0 BIPUSH 22 -> 整数22をスタックへPUSH ISTORE 0 -> ローカル変数0へスタックからPOP L1 LINENUMBER 9 L1 ILOAD 0 -> ローカル変数0をスタックへPUSH ICONST_3 -> 整数3をスタックへPUSH IADD -> スタックから2つPOP、両者を加算、答えをスタックへPUSH ISTORE 0 -> ローカル変数0へスタックからPOP L2 LINENUMBER 10 L2 LDC "TypeChecker" NEW java/lang/StringBuilder DUP INVOKESPECIAL java/lang/StringBuilder.<init> ()V LDC "value = " INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder; ILOAD 0 INVOKEVIRTUAL java/lang/StringBuilder.append (I)Ljava/lang/StringBuilder; INVOKEVIRTUAL java/lang/StringBuilder.toString ()Ljava/lang/String; INVOKESTATIC android/util/Log.i (Ljava/lang/String;Ljava/lang/String;)I POP
ちなみに、上記のバイトコードをデコンパイルすると、単純にJavaのプリミティブ型へ置き換えただけのソースコードになります。
int _value = 22; _value += 3; Log.i("TypeChecker", "value = " + _value);
ソースコード
ソースコードは整数22をオブジェクト(Int型のオブジェクト)として、プロパティを参照したり、関数を実行したり、できます。
そして、整数22のインスタンスの参照値が変数(_value)へ代入されたように、扱うことが出来ます。
これは、オブジェクトの振る舞い方です。
ただし、このオブジェクトの振る舞いはシステムよって付与された仮想的なものであり、実態はバイトコードのようなプリミティブ型であることに注意してください。
関連記事: