java 11 練習問題 ~ローカル変数型推論編~
java 11 練習問題 ~ローカル変数型推論編~
動作環境と問題内容について
javaの練習問題です。 出題範囲はjava 9 以降に追加された範囲を中心とします。このシリーズでは、ローカル変数型推論に関する問題を出題します。
難易度は Java SE 11 Programmer I の試験と同程度※を想定しています。
※ただし、場合によっては同試験には出題されない内容や形式が含まれることもあります。あくまでも難易度の目安として解答してください。
実行環境は以下の通りです。
javaのバージョン
javac 11
openjdk version “11” 2018-09-25
OpenJDK Runtime Environment 18.9 (build 11+28)
OpenJDK 64-Bit Server VM 18.9 (build 11+28, mixed mode)
※問題文に書いてあるプログラムを実行する際は自己責任で実行してください。
問題
次のプログラムを作成した。 a ~ d のうち、コンパイルエラーになる行をすべて選択せよ。1か所もコンパイルエラーがない場合は e を選択せよ。
プログラム(Sample.java)
import java.util.ArrayList; public class Sample{ public static void main(String[] args){ var list = new ArrayList<Object>(); //a list.add(1); //b list = new ArrayList<Integer>(); //c list.add(2); //d //コンパイルエラーはない //e } }
(解答はこちら)
解答
c. list = new LinkedList<Object>();
解説
java でローカル変数型推論を利用する場合、変数宣言時に代入された値からデータ型が推測される。
今回の変数宣言箇所(問題文中の選択肢 a の行)は
var list = new ArrayList<Object>();
となっている。よって、 変数listのデータ型はArrayList<Object>型となる 。
a. var list = new ArrayList<Object>();
変数宣言・代入ともに問題はない
b. list.add(1);
add()メソッドを利用してArrayListに値を格納している。ArrayListのジェネリクスではObject型が指定されているが、1は格納可能。特に問題はない。
c. list = new ArrayList<Integer>();
変数listに新しくインスタンス化したオブジェクトを代入しようとしている。インスタンス化されたオブジェクトはArrayList<Integer>型、変数listのデータ型はArrayList<Object>型となっている。
どちらも同じArrayList型に見えるが、 ジェネリクスで指定されているデータ型が異なっている 。
たとえ同じArrayListでも、 ジェネリクスで指定されているデータ型が異なる場合、異なるデータ型となる 。
今回のように、 ジェネリクスで指定されているデータ型に親子関係があっても、ArrayList<Object>型とArrayList<Integer>型に親子関係はない 。
以上から、代入できないのでコンパイルエラーとなる。
d. list.add(2);
選択肢bと同様。問題ない。
var について、詳しくはこちらの記事を参照
まとめ
java 10 からは、ローカル変数型推論を用いた変数宣言ができるようになった。
javaのローカル変数型推論は、変数宣言時にデータの代入を行うが、その際にデータ型が決まる。 値の再代入時には型推論は行われない 。
正確に理解した上で、設計や実装時にはソースコードの保守性が下がらないように注意して利用する必要がある。
<<前回の問題はこちら | 第1問はこちら | 次の問題はこちら>>
オススメ!!→ java 11 の問題はこちら オススメ!!→ java 8 の問題はこちら オススメ!!→ javaのプログラム作成練習問題はこちら オススメ!!→ ローカル変数型推論の使い方と注意点