SQLを使うプログラムではDateクラスに要注意JavaTips 〜Javaプログラミング編

» 2007年01月24日 10時00分 公開
[平野正喜@IT]

 Javaのクラス名はパッケージ名によって修飾されますので、パッケージが異なれば同じクラス名であっても構いません。J2SEが提供するパッケージの中にも、同じ名前のクラスが存在します。その一例が、java.utilパッケージとjava.sqlパッケージの両方にあるDateクラスです。

 この2つのパッケージを利用することが初めから分かっているプログラムで、java.utilパッケージのDateクラスを使う場合は、「java.util.Date」というように完全修飾で指定すれば、何も問題はありません。

Dateクラスが招きやすいトラブルの例

 トラブルを招きやすいのは、java.utilパッケージのDateクラスを使っているプログラムに、SQL処理を追加するために、java.sqlパッケージのimportを追加した場合です。この場合、非常に分かりづらいエラーが表示されてしまいます。

 非常に簡単な一例を示します。下記はjava.utilパッケージのDateクラスを使っているクラスにjava.sqlパッケージのimportを追加した結果です。

図1 「型 Date はあいまいです」というエラーになる 図1 「型 Date はあいまいです。」というエラーになる

 見てのとおり、「型 Date はあいまいです。」という意味のやや分かりづらいエラーになります。このメッセージは「java.utilパッケージ全体(*)と、java.sqlパッケージ全体(*)をimportしているが、Dateクラスはその両方にあるので、どちらを指しているかあいまいである」という意味です。

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.sql.Dateクラスはjava.util.Dateクラスのサブクラスです。 しかも、推奨されていないメソッドを除けば、オーバーライドしているメソッドはsetTime(long)toString()のみです。よって、この2つのメソッドを使っていなければ、java.util.Dateクラスをjava.sql.Dateクラスに単純に置き換えても大丈夫、と思われるかもしれません。しかし、下記の通りそうではありません。

図2 コンストラクタがエラーになる 図2 コンストラクタがエラーになる

 見てのとおり「コンストラクター Date() は未定義です。」というエラーになります。このメッセージのとおりで、java.util.Dateクラスにはパラメータの無いコンストラクタ(Date())がありますが、java.sql.Dateクラスにはありません。このクラスのコンストラクタは(推奨されていないものを除くと、)Date(long)しかないのです。

 同じクラス名で、しかも、スーパークラスとサブクラスの関係ですので、非常に間違えやすい一例といえるでしょう。

Profile

RunDog.org

平野正喜


Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。