ここでは、当社の新人研修受講者に向けて、基本情報のJavaの過去問を掲載しています。

想定しているのは、NetBeansなどのIDEにコピー・ペーストしたうえで、自分の正しいと思う答えを埋めて動作を確認するという使い方です。


次の Java プログラムの説明及びプログラムを読んで,設問1,2に答えよ。

(Javaプログラムで使用するAPIの説明は、IPAの過去問を参照ください。)

〔プログラムの説明〕

 D君は,社内向けの応用プログラム(以下,アプリケーションという)で共通に使うライブラリを開発するチームに属している。ライブラリの次のバージョンで,時間に関するクラスを幾つか用意することになり,D君は期間(時間間隔)を表すクラス Period の開発を担当することになった。このクラスは,“有効期間は,今週月曜日の午前 0 時から金曜日の終わりまで(土曜日の午前 0 時以降は,無効)”など, ある日付及び時刻(以下, 日時という)から別の日時までの時間間隔を表すことを想定している。期間の基準になる日時を始点,終わりを表す日時を終点という。また,ある始点から過去に遡って期間を表すことも想定している。D君が定めたクラス Period の外部仕様は,次のとおりである。

 クラス Period は,始点から終点までの期間を表す。期間には,始点は含まれるが終点は含まれない。始点と終点が同じ日時の場合は,期間が空であると定義し,いかなる日時も含まないものとする。

(1) コンストラクタは,引数で与えられた始点(start)と終点(end)から期間を表すインスタンスを生成する。日時は,クラス Date のインスタンスで与えられ,協定世界時 1970 年1月1日午前 0 時(以下,この日時をエポックという)以降でなければならない。引数 start 又は end が null の場合は, NullPointerException を,日時がエポックよりも前の場合は, IllegalArgumentException を投げる。

(2) メソッド getStart:始点を返す。

(3) メソッド getEnd: 終点を返す。

(4) メソッド getLength:期間の長さ(ミリ秒)を返す。終点が始点よりも前の場合は,負の値で返す。期間が空の場合は,0 を返す。

(5)メソッド isBackward:終点が始点よりも前の場合は,true を返す。それ以外は,false を返す。期間が空の場合は,false を返す。

(6)メソッド contains:引数で与えられた日時が期間に含まれる場合は,true を返す。それ以外は,false を返す。期間が空の場合は,false を返す。引数が,null の場合は, NullPointerException を投げる。

 この仕様でチームの承認を得て,次のプログラム1を作成した。

[プログラム1]

 次に,D君は,テスト用にプログラム2を作成した。問題が検出されなければ, プログラム2は何も出力せずに終了する。問題を検出した場合は,RuntimeException を投げる。

[プログラム2

設問1 プログラム1及び2中の に入れる正しい答えを, 解答群の中から選べ。ただし,プログラム2を実行したとき,例外は発生せず正常に終了するものとする。

a~c に関する解答群

ア !=       イ <       ウ <=
エ ==       オ >       カ  >=

d,e に関する解答群

ア IllegalArgumentException

イ IllegalArgumentException.class

ウ IllegalArgumentException.getClass()

エ new IllegalArgumentException()

オ new NullPointerException()

カ NullPointerException

キ NullPointerException.class

ク NullPointerException.getClass()

設問2 次の記述中の に入れる正しい答えを, 解答群の中から選べ。

 チーム内でのコードレビューも終わり,クラス Period を含むライブラリが評価版として 社内にリリースされた。それからしばらくして,アプリケーション開発チームから,アプリケーションの実行中に Period のインスタンスが表す期間が変わってしまうという指摘を 受けた。D君は,プログラムを見直したがクラスもフィールドも最終(final)なので,生成後にインスタンスの状態が変化することはないと考えた。そこで,D君は,アプリケーション開発チームと一緒にデバッグを行つた。
 その結果,アプリケーションでは,Period のメソッド getStart で始点を取得し,その Date インスタンスの表す日時を変更して別の Period のインスタンスを生成するときの引数に使用していることが分かった。これが原因で,先に生成済みのPeriod のインスタンスの始点が変更されていた。すなわち,Period インスタンス自体は不変でも,それから参照される Date インスタンスは可変なので,表している期間が変わってしまうことがある。したがって,Period のインスタンスで 始点及び終点を保持する場合は,外部からの変更ができないようにする必要がある。また,クラス Date は,最終(final)ではないので,どのような下位クラスでも 作成可能であり,上書きしたメソッドについて挙動の変更が可能である。これらは,データの改ざんを許すことになるので,セキュリティ上の問題でもある。これらの問題を修正するために,D君は,クラス Period に次の変更を加えた。

(1) コンストラクタの処理において,this.start の代入文の右辺を new Date(start.getTime()) に変更した。this.end の代入文についても 同様の変更をした。この変更によって,フィールド start 及び end は,それぞれ引数と同じ値をもつ別の java.util.Date のインスタンスを参照する。

(2) メソッド getStart の返却値を/*  f  */ に変更した。 メソッド getEnd についても同様の変更をした。 D君は,プログラム2のメソッド main の α で示した部分に次のプログラムを 追加し,正しく修正されたことを確認した。

f に関する解答群

ア (Date) start.clone()    イ null

ウ start.clone()       エ start.getTime()

オ start.setTime(Start.getTime())

g に関する解答群

ア 0        イ DELTA       ウ DELTA * 2

エ DELTA*3    オ DELTA / 2      カ DELTA / 3