Javaのクラス名はパッケージ名によって修飾されますので、パッケージが異なれば同じクラス名であっても構いません。J2SEが提供するパッケージの中にも、同じ名前のクラスが存在します。その一例が、java.utilパッケージとjava.sqlパッケージの両方にあるDateクラスです。
この2つのパッケージを利用することが初めから分かっているプログラムで、java.utilパッケージのDateクラスを使う場合は、「java.util.Date」というように完全修飾で指定すれば、何も問題はありません。
トラブルを招きやすいのは、java.utilパッケージのDateクラスを使っているプログラムに、SQL処理を追加するために、java.sqlパッケージのimportを追加した場合です。この場合、非常に分かりづらいエラーが表示されてしまいます。
非常に簡単な一例を示します。下記はjava.utilパッケージのDateクラスを使っているクラスにjava.sqlパッケージのimportを追加した結果です。
見てのとおり、「型 Date はあいまいです。」という意味のやや分かりづらいエラーになります。このメッセージは「java.utilパッケージ全体(*)と、java.sqlパッケージ全体(*)をimportしているが、Dateクラスはその両方にあるので、どちらを指しているかあいまいである」という意味です。
この問題を解決する方法は2つあります。
1つは「Date d = new Date();」を「java.util.Date d = new java.util.Date();」と完全に指定する方法です。今回の例では、こうすることで「import java.util.*;」が不要になります。
もう1つの方法は、「import java.util.*;」を「import java.util.Date;」に変更し、パッケージ全体をimportしないようにする方法です。java.utilパッケージにあるクラスのうち、利用しているのがDateクラスのみであれば、この方法が最も簡単です。
なお、内部ルールとして、importの「*」指定を禁止している場合は、このようなトラブルは起こりづらくなりますが、トラブルの可能性が皆無とは限りませんので、油断は禁物です。一例として、下記のような場合があるからです。
実は、java.sql.Dateクラスはjava.util.Dateクラスのサブクラスです。 しかも、推奨されていないメソッドを除けば、オーバーライドしているメソッドはsetTime(long)とtoString()のみです。よって、この2つのメソッドを使っていなければ、java.util.Dateクラスをjava.sql.Dateクラスに単純に置き換えても大丈夫、と思われるかもしれません。しかし、下記の通りそうではありません。
見てのとおり「コンストラクター Date() は未定義です。」というエラーになります。このメッセージのとおりで、java.util.Dateクラスにはパラメータの無いコンストラクタ(Date())がありますが、java.sql.Dateクラスにはありません。このクラスのコンストラクタは(推奨されていないものを除くと、)Date(long)しかないのです。
同じクラス名で、しかも、スーパークラスとサブクラスの関係ですので、非常に間違えやすい一例といえるでしょう。
Copyright © ITmedia, Inc. All Rights Reserved.