import(ワイルドカードインポートと型名の曖昧性)難易度 高無料
次のコードのコンパイル結果として正しいものを選べ。
1 import java.util.*;
2 import java.sql.*;
3 public class Q4 {
4 public static void main(String[] args) {
5 Date d = new Date();
6 System.out.println(d);
7 }
8 }
- Aコンパイルエラー(
Dateの参照がjava.util.Dateとjava.sql.Dateのどちらか曖昧) - Bコンパイル成功。後に書かれた
import java.sql.*;が優先されjava.sql.Dateとして解決される - Cコンパイル成功。
java.langと同じパッケージが優先されjava.util.Dateとして解決される - Dコンパイルエラー(
java.utilとjava.sqlを同時にインポートすること自体が禁止されている)
正解・解説・誤答理由・ひっかけを見る▼ open
✓ 正解:AAI作成・独立検証済
解説
ワイルドカードインポート(
各誤答が違う理由import パッケージ.*;)は、そのパッケージ配下の全ての型を「使用可能な候補」として取り込むだけで、
実際にどの型を指すかはコード中で使われた時点で解決される。
java.util と java.sql の両方に Date という同名クラスが存在する。
両方をワイルドカードインポートした状態で単に Date と書くと、コンパイラはどちらの Date か一意に決定できず、曖昧な参照としてコンパイルエラーになる。
解消するには java.util.Date d = new java.util.Date(); のように完全修飾名で指定するか、片方だけを単一型インポート(import java.util.Date;)にする。
- Bワイルドカードインポートに「後勝ち」の優先順位は無い。同名クラスが複数パッケージに存在する場合はコンパイラが一意に決定できずコンパイルエラーになる。
- C
java.util・java.sqlのどちらもjava.langではなく暗黙インポートの対象外。両者は対等な候補として扱われ、優先順位による自動解決は行われない。 - D異なるパッケージを同時にインポートすること自体は合法。問題となるのは、それらの中に同名の型が実在し、かつコード中で曖昧に参照されたことである。
ひっかけ: 「ワイルドカードインポートは名前解決の手間を省くだけで安全」という思い込みが罠。同名クラスが複数パッケージに存在する場合はワイルドカード同士が衝突し、コンパイルエラーになる。単一型インポート(
import java.util.Date;)同士で衝突する場合はそもそも記述時点でエラーになる点との違いにも注意(ワイルドカードは"使用時"に判明する)。コマンド例と想定される挙動(未実行)
javac でコンパイル:
Q4.java:5: error: reference to Date is ambiguous
Date d = new Date();
^
both class java.util.Date in java.util and class java.sql.Date in java.sql match
→ コンパイル不成立(実行に至らない)。AIが作成し、独立した検証を経た解説です(有資格者による監修は経ていません)