2024年12月30日

javaにハマるきっかけとなったプリミティブ型・ラッパークラスについて解説!

カテゴリー:java
サムネイル

どうもむらまさです。
エンジニア歴3年目ぐらいの人に問いたい。
Booleanbooleanの違いをご存じでしょうか?
恥ずかしながら私は最近まで2種類あることすら知りませんでした。
プリミティブ型の存在を上司から聞き、「なんじゃそりゃ」と調べていくうちにjavaにハマりました。
私がjava面白いと思えたきっかけであるプリミティブ型・ラッパークラスについて解説します!

プリミティブ型とは?

プリミティブ型とは、値型や基本データ型とも呼ばれるもので、Javaプログラムで扱う最も基本的なデータ型です。
Javaには以下の8種類のプリミティブ型があります。

  • byte: 8ビット整数型
  • short: 16ビット整数型
  • int: 32ビット整数型(最も一般的に使われる整数型)
  • long: 64ビット整数型
  • char: Unicode文字を扱う(16ビット)
  • float: 単精度浮動小数点型(32ビット)
  • double: 倍精度浮動小数点型(64ビット)
  • boolean: 真偽値型(true または false)

プリミティブ型の特徴

【軽量でメモリ効率が良い】

オブジェクトを扱う場合は参照先のアドレスが変数に格納されます。
対してプリミティブ型は値そのものを直接メモリに格納するため、メモリ効率が良いです。

int num = 10;
Integer num2 = Integer.valueOf(20);
// またはオートボクシング
Integer num3 = 20;

上記の場合、num 変数には 10 という値が格納されます。一方、num2num3 の中身はインスタンス(オブジェクト)の参照先アドレスです。実際の値 20 はインスタンス内部に格納されます。

  • メソッドを持たない

    プリミティブ型はオブジェクトではないので、toString()のようなメソッドは呼び出せません。

    int num = 10;
    num.toString() //コンパイルエラー
    
  • NULLが許容されない

    プリミティブ型は null を代入できません。
    しかいクラスのフィールドとして宣言した場合には、
    数値型は0、boolean 型は false が初期値となります。
    ※メソッド内のローカル変数は初期化なしに使うとコンパイルエラー になるので注意

public class PrimitiveExample {
    // クラスフィールド
    static int classFieldInt;      //自動的に0がセットされる
    static boolean classFieldBool; //自動的にfalseがセットされる

    public static void main(String[] args) {
        // ローカル変数
        // int localInt; 初期化していないためコンパイルエラー
        
        
        System.out.println("クラスフィールド int: " + classFieldInt);  
        // 結果 → クラスフィールド int: 0 
        System.out.println("クラスフィールド boolean: " + classFieldBool); 
        // 結果 → クラスフィールド boolean: false  
    }
}

ラッパークラスとは?

ラッパークラスとは、プリミティブ型をオブジェクトとして扱うためのクラス群のことです。
例えば、boolean 型をオブジェクトとして操作したい場合、対応するクラスが Boolean となります。

プリミティブ型

ラッパークラス

byte

Byte

short

Short

int

Integer

long

Long

char

Character

float

Float

double

Double

boolean

Boolean

ラッパークラスの特徴

  • オブジェクトとして扱える

    そのため、ListMap などのコレクションに格納可能です。

    public class PrimitiveExample {
        public static void main(String[] args) {
            List<Integer> list = new ArrayList<>();
            // 結果 → エラーなし
            List<int> list = new ArrayList<>();  
            // 結果 → コンパイルエラー
        }
    }
  • 便利なメソッドを持つ

    例えば、Integer.parseInt("123") のように文字列を数値に変換するなど、 プリミティブ型にはないメソッドが多く存在します。

    • Integer.parseInt("123"): 文字列をint型に変換
    • Double.valueOf("3.14"): 文字列をDoubleオブジェクトに変換
    • Boolean.parseBoolean("true"): 文字列をboolean型に変換
  • デフォルト値はnull

    ラッパークラスはオブジェクトなので、初期化されていない場合は null が代入されます。
    そのため、アンボクシング時に NullPointerException が起こらないよう注意が必要です。

  • イミュータブル(不変)である

    ラッパークラスのインスタンスは一度作られると、その値を変更できません。
    値変更時には内部的に新たなオブジェクトを生成します。

プリミティブ型とラッパークラスの違い

特徴

プリミティブ型

ラッパークラス

オブジェクト

×

メソッド

なし

あり

メモリ使用量

少ない

多い

コレクション格納

不可

可能

デフォルト値

【クラスフィールドの場合】
0, false
【ローカル変数の場合】
不可能

null

結論

プリミティブ型は軽量でメモリ効率が良く、演算処理がメインの場面に向いています。
一方ラッパークラスはオブジェクトとして扱えるため、
コレクションに格納したり、便利なメソッドを利用したりできるのが利点です。
ただ、現場によってはラッパークラスは使わず基本プリミティブ型だけ使われてることもあります。
その場合は他と合わせた型を使用するのが無難ですが、
何も知らずに他と合わせるのと、違いを知ったうえで合わせるのでは天と地の差があります。
分からないことがあればDM頂けば知っている限りお答えしますので気軽にDMください。