varによるローカル変数型推論を理解する
varは初期化式からローカル変数の型をコンパイラに決めさせる記法です。動的に型が変わる仕組みではありません。数値、配列、参照型の例から、推論される型と後から許される操作を区別します。
この単元で学ぶこと
- 初期化式から固定される型を求める
- varを使えない宣言を判定する
- ループ・参照・配列での型推論を追う
本文解説
型名を省略する宣言 int n=5;は型を明示し、var n=5;は右辺の5からintを推論します。どちらもnの型はintです。var n=5;System.out.print(n+2);は7になります。varはJava 10以降のローカル変数型推論で、ここではJava 17として扱います。
型は途中で変わらない var n=5;n=8;はintへの再代入なので可能です。n=2.5;はdoubleからintへの暗黙の代入ができずコンパイルエラーです。小数を扱いたいなら最初からvar n=5.0;やdouble n=5;と宣言します。後の用途から過去の推論をやり直すことはありません。
リテラルの型が出発点 var a=5;はint、var b=5L;はlong、var c=5.0;はdouble、var d=5.0f;はfloatです。var a=5;System.out.print(a/2);は整数同士の除算で2になります。表示する段階で小数に直すのではなく、演算に参加する型が除算の方法を決めます。
初期化式が必要 var n;では型を決める情報がなく、var n=null;では有用な変数型を推論できません。いずれもコンパイルエラーです。String s=null;なら型が明示されています。var s=(String)null;でもキャストされた式の型がStringなので宣言できますが、s.length()を実行すればnull参照による例外になります。
一つの宣言には一変数 var a=1,b=2;は認められません。var a=1;var b=2;と分けます。varはこの形ではローカル変数の型に使い、通常のフィールドやメソッドの戻り値型・通常の仮引数型の代わりにはできません。ローカル変数を宣言する位置も通常の型を使う場合と同様、構文上許される位置が必要です。
配列には式を与える var a=new int[]{2,4};はint[]を推論し、a[1]は4です。var a={2,4};という配列初期化子だけの形は使えません。またvar a[]=new int[2];のように宣言側へ角括弧を付けられません。配列型も右辺のnew int[2]などから推論します。
参照型にも型検査がある var s="cat";はStringなのでs.length()が呼べます。var x=(Object)"cat";はObjectなので、x.length()は宣言された型で見つからずコンパイルエラーです。実物が文字列であることだけでは、Object型の変数を介したメソッド呼出しを許しません。
ループとfinalで使う for(var i=0;i<3;i++)のiはintで、通常のforと同じ範囲で使えます。for(var n:new int[]{2,3})では要素型intを推論します。final var limit=3;なら再代入できませんが、varだけなら再代入可能です。省略記法と変更禁止は別々の選択です。
図解
重要ポイント
- 型は初期化式に基づきコンパイル時に決まる。
- 初期値なし・nullだけ・複数変数の同時宣言は使えない。
- 推論された型と代入される実際の値を区別する。
間違えやすい点
- varはObjectの別名でも動的型でもない。
- 配列初期化子だけではなくnewと型が必要。
- varで宣言してもfinalが自動で付くわけではない。
用語解説
- 型推論
- 式の情報からコンパイラが変数の型を決めること。
- 初期化式
- 変数宣言時に初めの値を与える式。
- 静的型
- 実行前の型検査に使う型。varでも固定される。
関連教材
参考資料
教材データに登録された参考リンクです。リンク先の内容や更新日は提供元でご確認ください。
- https://www.oracle.com/jp/education/certification/javase-17-programmer-1/
- https://docs.oracle.com/javase/specs/jls/se17/html/jls-14.html#jls-14.4
- https://docs.oracle.com/javase/specs/jls/se17/html/jls-5.html#jls-5.1.8
- https://docs.oracle.com/javase/specs/jls/se17/html/jls-15.html#jls-15.23
- https://docs.oracle.com/javase/specs/jls/se17/html/jls-15.html#jls-15.25
- https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Integer.html
- https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Objects.html
- https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/ArrayList.html
確認問題の出題・採点や学習履歴の保存にはログインが必要です。