Java入門|型変換とキャスト

型の違いがわかると、Javaの計算結果が変わる理由までしっかり見えてきます。

Javaでは、変数に値を入れるときや、計算結果を別の変数に代入するときに、がとても大切になります。これまで int 型や double 型などを使ってきましたが、実は演算子や代入のしくみは、こうした型と深く関係しています。見た目には同じような数字でも、整数として扱うのか、小数を含む数として扱うのかによって、できることや結果が変わるのです。

たとえば、整数を小数型の変数に入れることはできても、その逆はそのままではできない場合があります。これはJavaが厳密に型を管理しているからです。このルールを理解しておかないと、「なぜこのコードは動くのに、こちらはエラーになるのだろう」と戸惑ってしまいます。

そこで大切になるのが、型変換キャストです。型変換を理解すると、Javaが値をどのように別の型へ変えて扱っているのかが見えてきます。また、キャストを理解すると、自分の意思で型を変える書き方がわかるようになります。これは、より実践的なプログラムを書くうえで欠かせない知識です。

ここでは、まず大きなサイズの型へ代入するときの型変換から確認し、そのあとで小さなサイズの型へ代入するときに必要になるキャスト演算子について、サンプルプログラムを使いながら丁寧に見ていきましょう。

大きなサイズの型に代入する

まずは、比較的わかりやすいケースから見ていきましょう。Javaでは、一般に小さなサイズの型の値を、大きなサイズの型の変数に代入することができます。

たとえば、int 型の値を double 型の変数に代入することができます。これは、double 型のほうが、int 型よりも広い範囲や小数を扱えるからです。

class Sample8
{
    public static void main(String[] args)
    {
        int price = 980;

        System.out.println("商品価格は " + price + " 円です。");

        System.out.println("double型の変数に代入します。");
        double dprice = price;

        System.out.println("商品価格は " + dprice + " 円です。");
    }
}

ファイル名:Sample8.java

実行結果を確認しよう

このプログラムを実行すると、次のようになります。

商品価格は 980 円です。
double型の変数に代入します。
商品価格は 980.0 円です。

最初は int 型の変数 price に 980 が入っています。そのあと、それを double 型の変数 dprice に代入しています。すると、980 という整数の値が、980.0 という double 型の値に変換されて代入されます。

ここで大切なのは、Javaが自動的に型を変換していることです。このように、型が自動的に変わることを型変換といいます。

なぜ自動で変換できるのか

では、なぜ int から double へは、そのまま代入できるのでしょうか。

理由は、double 型のほうが、int 型より表現できる情報が広いからです。int 型は整数しか扱えませんが、double 型は整数も小数も扱えます。そのため、980 という int 型の値は、double 型でも無理なく表現できます。

イメージとしては、小さい箱の中身を、大きい箱へ移すような感覚です。小さい箱に入っていたものは、大きい箱にもそのまま入れられます。

表で整理すると、次のようになります。

代入そのままできるか理由
int → doubleできるdouble のほうが広い範囲を扱える
int → longできるlong のほうが大きい範囲を扱える
double → intそのままではできないint では小数を表せない

この図では、int 型の 980 という値が、double 型の変数へ移される流れを示しています。右側の double 型では 980.0 として表されていて、整数が小数型に変換されていることがわかります。

ここでのポイントは、小さな型から大きな型への代入では、Javaが自動的に型変換してくれるということです。

小さなサイズの型に代入する

では、逆の場合はどうでしょうか。今度は、double 型の値を int 型の変数へ代入することを考えてみます。

ファイル名:Sample9.java

class Sample9
{
    public static void main(String[] args)
    {
        double weight = 58.7;

        System.out.println("体重は " + weight + " キログラムです。");

        System.out.println("int型の変数に代入します。");
        int iweight = weight;

        System.out.println("体重は " + iweight + " キログラムです。");
    }
}

このコードは、そのままではコンパイルできません。

なぜコンパイルできないのか

理由は、double 型の値には小数部分が含まれることがあり、int 型ではその小数部分を表せないからです。

今回の例では、weight には 58.7 が入っています。これを int 型の変数にそのまま入れようとすると、Javaは「小数を含む値を整数型へそのまま代入するのは危ない」と判断します。なぜなら、情報の一部が失われる可能性があるからです。

つまり、大きな型から小さな型への代入では、情報が入りきらないことがあるため、自動では変換してくれないのです。

小さな型へ代入するにはキャストが必要

このようなときに使うのが、キャスト演算子です。

キャスト演算子の書き方は次の通りです。

(型名)式

この書き方は、「この式の値を、かっこの中で指定した型に変換してください」という意味になります。

先ほどのプログラムは、次のように書き換えるとコンパイルできるようになります。

ファイル名:Sample9.java

class Sample9
{
    public static void main(String[] args)
    {
        double weight = 58.7;

        System.out.println("体重は " + weight + " キログラムです。");

        System.out.println("int型の変数に代入します。");
        int iweight = (int)weight;

        System.out.println("体重は " + iweight + " キログラムです。");
    }
}

実行結果を見てみよう

この修正版を実行すると、次のようになります。

体重は 58.7 キログラムです。
int型の変数に代入します。
体重は 58 キログラムです。

ここで注目したいのは、58.7 が 58 になっていることです。

キャストすると何が起こるのか

double 型の 58.7 を int 型に変換すると、小数点以下は切り捨てられます。つまり、58.7 は 58 になります。

ここで気をつけたいのは、四捨五入ではないということです。Javaのこの型変換では、小数点以下が単純に切り捨てられると考えましょう。

たとえば、次のようになります。

元の値int にキャストした結果
58.758
12.912
3.13
160.5160

このように、小数部分は失われます。そのため、キャストは便利ですが、情報が失われる可能性がある変換でもあります。

この図では、double 型の 58.7 が、キャストによって int 型の 58 に変換される流れを示しています。小数点以下が切り捨てられるため、元の値と完全に同じ情報を保てないことがわかります。

この図から、小さな型への代入では、自分で型を変換する意思を明示する必要があるということが見えてきます。

キャスト演算子とは何か

キャスト演算子は、Javaに対して「この型へ変換して使います」と明示するための書き方です。

たとえば、

(int)weight

なら、weight の値を int 型へ変換する、という意味です。

同じように、

(double)price

と書けば、price の値を double 型に変換することもできます。

つまり、キャスト演算子は、指定した型へ値を変換するための演算子です。

大きな型への代入でもキャストは書ける

なお、キャスト演算子は、大きな型へ変換するときにも使うことができます。

たとえば、

double dprice = (double)price;

のように書くこともできます。

ただし、この場合は、もともと自動で型変換されるので、キャストを書いても結果は同じです。

つまり、

double dprice = price;

double dprice = (double)price;

は、どちらも同じ結果になります。

最初の学習段階では、自動で変換される場合は無理にキャストを書かなくてもよいと考えて大丈夫です。

自動の型変換と明示的な型変換の違い

ここまでの内容を整理すると、型変換には大きく2つの考え方があります。

種類説明
自動の型変換小さい型から大きい型へ、Javaが自動で変換するint → double
明示的な型変換大きい型から小さい型へ、自分でキャストを書くdouble → int

この違いはとても重要です。Javaは安全に変換できる場合だけ自動で型を変えます。危険がある場合は、プログラマが「それでも変換します」と明示しなければなりません。

サンプルプログラムの流れを整理しよう

ここで、今回の2つのサンプルの流れを並べて見てみましょう。

サンプル内容ポイント
Sample8.javaint 型を double 型へ代入自動で型変換される
Sample9.javadouble 型を int 型へ代入キャストが必要になる

Sample8 では、整数が小数型へ移るだけなので安全です。Sample9 では、小数型から整数型へ移るため、小数部分が失われる可能性があります。そのため、Javaはキャストを要求します。

型変換を理解すると演算もわかりやすくなる

型変換とキャストは、代入の場面だけでなく、演算の理解にもつながります。たとえば、整数どうしの割り算と、小数を含む割り算で結果が違うのも、型の違いが関係しています。

つまり、型を意識できるようになると、

  • なぜこの値になるのか
  • なぜこのコードはコンパイルできるのか
  • なぜ小数が消えるのか

といったことが、すっきり理解できるようになります。

Javaは型をしっかり管理する言語なので、型変換やキャストの考え方は、今後も何度も出てきます。ここでしっかり感覚をつかんでおくと、この先の学習がかなり進めやすくなります。

覚えておきたいポイント

最後に、この内容で特に大切な点を整理しておきます。

ポイント内容
小さな型から大きな型へは代入できるint から double などは自動で型変換される
大きな型から小さな型へはそのまま代入できないdouble から int などは自動では変換されない
キャスト演算子を使う(型名)式 で型を明示的に変換する
小さな型へ変換すると情報が失われることがある小数点以下は切り捨てられる
キャストは自分で変換の意思を示す書き方Javaに明示的に指示するために使う

型変換とキャストは、最初は少し細かく感じるかもしれません。でも、ここがわかるとJavaの式や代入のしくみがかなり深く理解できるようになります。数字をただ扱うだけでなく、「どの型として扱っているのか」を意識できるようになることが、Javaの学習ではとても大切です。