【Java入門】キャスト(型変換)とアップキャスト、ダウンキャスト

本多 農
書いた人 本多 農


侍エンジニア塾ブログは、未経験からWebアプリ開発と仕事獲得をサポートする
侍エンジニア塾のオウンドメディアです。
プログラミング学習を覗き見

こんにちは!侍エンジニア インストラクターの本多です。

みなさんは、ある型から別の型に変換するキャストという言葉は聞いたことがありますか?

この記事では、キャストについて

・キャストとは何か
・キャストの使い方

という基本的な内容から、

・クラスをアップキャストする方法
・クラスをダウンキャストする方法

といった応用的な内容に関しても解説していきます。

今回はキャストについて、使い方をわかりやすく解説します!

キャストとは

ある型から別の型に変換することをキャストといいます。

利用シーンとしては「型は変えたくないけど、一時的に別の型として扱いたい」といったことが考えられます。

例えば、整数型のテストの点数から、小数点以下第1位までの平均点を求めたい、などです。

キャストを使うためには、下記のように記述するのが基本パターンとなります。

基本型(プリミティブ型)のキャストから解説します。

キャストの使い方

キャストの使い方について、実際にコードを確認していきましょう。

暗黙的なキャストについて

まずは変数が自動的に型変換される例についてみてきましょう。

これからご紹介する例はint型の2つの変数で割り算を行う場合に、計算結果が自動的にint型になる例です。

自動的に型変換されることを暗黙的なキャストといいます。

実行結果:

このサンプルコードの実行結果を確認すると、3.3333…となってほしいところが、きれいに3.0となってしまいました。

確かに結果を代入する変数resultはfloat型になっているので、小数点以下も代入可能のようにみえます。

しかしi / j の計算をした時に、両者がint型なので結果も自動的にint型になります。

よって、小数点以下が切り捨てられて3となります。

その結果をfloat型に代入しても、整数3をfloat型に代入することになるので3.0となるだけです。

小数点以下まで計算するとすれば、最初から変数をfloat型で宣言するのが一番簡単です。

割り算でキャストが必要な場合

先ほどのサンプルコードでは、int型の2つの変数で割り算を行い結果が自動的にint型になりました。

小数点以下を含むfloat型の結果を得たい場合は、キャストを使って変更することが可能です。

サンプルコードで確認していきましょう。

実行結果:

このサンプルコードの実行結果を確認すると、想定通りの結果が得られました。

このように、元の変数の型はそのままで、一時的に宣言時とは別の型に置き換えることをキャストといいます。

今回はint型をfloat型にしましたが、それ以外にも基本型であれば基本的にキャストは可能です。

キャストができない場合の注意点

先ほどのサンプルコードでは、キャストについて確認しました。

ただし、以下のようなキャストはできません。

実行結果:

float型とdouble型では、double型の方が表現できる桁数が大きいです。

ということは、floatの最大桁数より大きい数値がiやjに入っていた場合は、より小さい桁数をもつ変数resultに押し込めようとしているので、エラーになります。

この例では、あえて大きい型にキャストして小さい型に代入しようとしました。

一方、桁数が大きい型で宣言した変数をより小さい型の変数に代入する際、キャストして型変換すると代入が可能になります。

精度保証の注意点

キャストする際は、元の基本型のデータ範囲とキャスト後の基本型のデータ範囲に注意する必要があります。

データ範囲が大きい基本型から小さい基本型へキャストすると精度が保証されません

ご注意ください。

サンプルコードで確認しましょう。

実行結果:

このサンプルコードでは、double型の最大値をint型にキャストして、int型の変数に代入しています。

エラーにはなりませんが、int型の最大値に置き換わってしまって精度が保証さず、意図しない値となっています。

クラスのアップキャスト

スーパークラスを継承するサブクラスがあるとします。

スーパークラスのオブジェクトにサブクラスのインスタンスを格納することをアップキャストといいます。

アップキャストはサブクラスからスーパークラスへ型変換されることになります。

アップキャストは自動的に行われる暗黙的型変換ということになります。

自動的に型変換が行われるのは、サブクラスがスーパークラスのすべてのメンバーを保証できるためです。

サブクラスからスーパークラスにアップキャスト

サブクラスからスーパークラスにアップキャストする場合についてサンプルコードで確認していきましょう。

実行結果:

このサンプルコードでは、SubClassのインスタンスsbをSuperClass型のオブジェクトscに格納しています。

scの型はSuperClassの型で、SubClassのメソッドをメンバに持つわけではありません。

したがって、method2メソッドを実行するとコンパイルエラーとなるのでコメントアウトしています。

どのフィールド変数、メソッドが使えるかはオブジェクトの型で決まります。

インスタンスの型がサブクラスでも、オブジェクトの型がスーパークラスなら、スーパークラスのフィールド変数およびメソッドしか使えません。

アップキャストの注意点

サブクラスのオブジェクトをスーパークラス型のオブジェクトでアップキャストする際、注意点があります。

スーパークラスとサブクラスに、同じ名前のフィールド変数やメソッドがある場合には、フィールド変数はスーパークラス、メソッドはサブクラスが優先される、という点です。

サンプルコードで確認しましょう。

実行結果:

このサンプルコードでは、SubClassはSuperClassを継承しています。

(1)は参照変数とsbともにSubClassなので、3と18が表示されたのは分かりますが、(2)は2と18と表示されています。

このことから、フィールド変数はスーパークラス、メソッドはサブクラスが優先されたのが分かります。

継承しているので、SubClassはSuperClassのメンバーを内包していますが、メソッドはオーバーライドして、フィールド変数は同じ名前のフィールド変数を宣言して隠蔽しています。

このような場合、アップキャストしたあとはどちらが優先されるのか、注意が必要です。

クラスのダウンキャスト

アップキャストとは逆に、サブクラスのオブジェクトにスーパークラスのオブジェクトを格納することをダウンキャストといいます。

スーパークラスからサブクラスにダウンキャスト

スーパークラスからサブクラスにダウンキャストする場合は明示的にダウンキャストを行う必要があります。

これはスーパークラスはサブクラスのすべてのメンバーを保証できないためです。

明示的にダウンキャストするには基本型のキャストの場合と同じように「()」を使って記述します。

また、ダウンキャストは一度アップキャストしたオブジェクトに対してのみ使用することができます。

アップキャストされていないオブジェクトをダウンキャストすると、ClassCastExceptionの例外が発生するので注意しましょう。

それではダウンキャストについてサンプルコードで確認しましょう。

実行結果:

このサンプルコードでは、まずサブクラスのインスタンスをスーパークラス型のオブジェクトに格納してアップキャストしています。

その後、明示的にダウンキャストしています。

ダウンキャストの注意点

先ほどアップキャストされていないオブジェクトをダウンキャストすると、ClassCastExceptionの例外が発生すると説明しました。

ダウンキャストができるか確認する方法があります。

それはinstanceof演算子を使う方法です。

instanceof演算子はオブジェクトが指定したクラス型もしくは指定したクラスを継承しているか比較します。

サンプルコードで確認していきましょう。

実行結果:

このサンプルコードでは、instanceof演算子を使ってダウンキャストできるか確認しています。

SuperClassのオブジェクトsc1にはSubClassのインスタンスを格納し、暗黙的にアップキャストされています。

そのためinstanceof演算子でサブクラスの型と比較するとtrueを返し、ダウンキャストが実行されています。

SuperClassのオブジェクトsc2はSubClassのインスタンスでもSubClassを継承したクラスのインスタンスでもないため、ダウンキャストは実行されていません。

このようにダウンキャストを使用する場合はClassCastExceptionの例外が発生しないように、instanceof演算子を使って確認するようにしましょう!

String型の型変換について知りたい方へ

この記事では基本型の型変換について説明しています。

String型の型変換については、こちらで詳しく説明していますので、ぜひ参考にしてくださいね

まとめ

この記事では、基本型やクラスのキャストを説明しました。

キャストは、一時的に宣言した型とは異なる型として扱いたいときに使われます。

基本型の場合は理解しやすいですが、クラスの場合はいろいろとルールがあって、最初は理解が難しいかもしれません。

使い方を忘れた場合、本記事を参考にしてくださいね!

Javaカリキュラム無料公開中!
この記事はJava入門完全攻略ガイド【基礎学習/アプリ開発/仕事獲得】の一部になります。このカリキュラムは、プログラミング入門者が、基礎学習からアプリ開発、さらには仕事獲得まで体系的に学べる内容となっています。

Java学習に必要な情報を一つにまとめていますので効率よくJavaを学ぶことが出来ます。この機会に是非活用していただければと思います。


33歳、未経験だった僕がフリーエンジニアになれた理由
現在フリーでWEBエンジニアをやられている濱口直行さん。33歳で、プログラミングを学び始め、約半年という短い期間で独立までされた学習ログを余すことなくインタビューさせていただきました。

プログラミングを学習中の方はもちろん、独立をお考えの方まで幅広く活用できる記事になっています。この機会に是非活用していただければと思います。


最短でJavaを習得したい方へ

もし、あなたが、

「難しすぎて学習が全然進まない」
「学習量が膨大でゴールが見えない」
「エラーを解決するのに何日もかかってしまう」

など、プログラミング学習やキャリアに関してお困りであれば、まずは『無料体験レッスン』にお申し込み下さい。

あなたにとって、最適の解決策をご提案させていただきます。

詳しくは下の画像から詳しいサービス内容をご確認ください。

cta_bannar-java2

非常識な結果を出した卒業生

活躍する現役エンジニア

人気記事セレクション

LINEで送る
Pocket

この記事が気に入ったら
いいね!をしてフォローしよう

最新情報をお届けします

書いた人

本多 農

本多 農

関西在住のITエンジニアです。普通の会社に勤務しながら、侍エンジニアのインストラクター、ライターとして活動しています。