新人エンジニア研修で知っておきたい列挙型の使い方
※この章は研修時間の都合により丸ごとスキップすることがあります。
なぜ、列挙型の理解が重要なのか、その理由。
この記事では、弊社の新人エンジニア研修の参考にJava8を解説します。
前回はコレクションとジェネリクスについて解説しました。
今回は日付/時刻と列挙型について解説します。
Javaには過去の経緯から日付/時刻するクラスはたくさんあります。
しかし、当社の新人エンジニア研修ではjava.timeパッケージの中のクラスの特定の機能に限定してお伝えします。
詳しい使い方は必要に応じて調べてください。
目次
1.現在日時の取得
今現在を表すインスタンスはLocalDateTimeクラス(標準API)のnowメソッドで取得できます。
<結果の例を表示する>
2021-02-10T13:37:43.995
結果は「西暦-月-日T時:分:秒」の形で表示されました。
Tは単なる区切り文字で意味はありません。
インスタンスから年だけ、月だけ、日だけ、、、のように一部の要素を取り出すには以下のようにgetで始まるメソッドを使用します。
<結果の例を表示する>
2021年
FEBRUARY月
10日
WEDNESDAY曜日
13時
51分
55秒
41000000ナノ秒
ところでここで出てきた「FEBRUARY」、「WEDNESDAY」といった文字列は何でしょうか?
実はこれらは列挙型と呼ばれるJavaの型の一つです。
列挙型は複数の定数をひとつにまとめておくことができる型です。
月はJANUARYから始まって12個しかありません。
曜日はMONDAYから始まって7個しかありません。
このように限定的なものは列挙型にすると色々と便利なのです。
列挙型については本章でこの後学んでいきます。
2.特定の日付の扱い
特定の日付のインスタンスを作成するにはLocalDateクラス(標準API)のstaticメソッドofを使います。
以下は1995年4月19日生まれの人の誕生日を表示しているソースコードです。
<結果を表示する>
1995-04-19
なお、ありえない日付を指定すると例外が発生します。
<結果を表示する>
java.time.DateTimeException: Invalid date 'APRIL 31'
null
4月31日というのはありえないため例外が発生しました。
3.日付の書式を指定する
日付の書式を指定するには、クラスDateTimeFormatter(標準API)を使います。
先にサンプルコードを見てみます。
クラスDateTimeFormatterのofPatternメソッドは引数として書式とロケールという同じ言語を共有する区域を指定します。
上記の例で書式は、uuuuが西暦を、Mが月を、dが日付を、Eが曜日をそれぞれ意味しています。
例えば、月を2桁で表示したければMM、日付を2桁で表示したければddとします。
試してみてください。
ロケールはLocale.JAPANESEとなっています。
DateTimeFormatterのofPatternメソッドの戻り値に対してメソッドチェーンでformatメソッドを呼んで、
引数にクラスLocalDateのインスタンスを渡せば、上記のような結果になります。
なお、和暦の表示も可能です。
以下のサンプルコードを御覧ください。
<結果を表示する>
令和 3年2月10日(水)
4.時刻の扱い
時刻を表すクラスは、クラスLocalTime(標準API)です。
クラスLocalTimeのofメソッドの引数に時間(0~23)と分(0~59)をカンマで区切って指定します。
以下のサンプルコードを御覧ください。
<結果を表示する>
00:00
23:59
なお、上記の例では分までしか指定していませんが、秒、ナノ秒まで指定が可能です。
第3、第4引数を使います。
時刻の比較も可能です。
クラスLocalTimeのインスタンスメソッドisBeforeやisAfterを使います。
次のサンプルコードをご覧ください。
<結果を表示する>
true
false
このようにたくさんのクラス、メソッドがあります。
とても全ては紹介しきれないので、この新人エンジニア研修の期間では紹介しきれません。
5.Enum(列挙型)とは
Enum(イーナム)型は複数の定数をひとつにまとめることが出来る型のことです。
ここではクラスEnum(標準API)について簡単な説明をします。
さきほどパッケージ java.timeで月や曜日でEnumが使われている例を見ました。
Enumは限定されたものを列挙するのに使うと便利です。
みなさんもオリジナルのEnumを作成して利用することができます。
Enum型の宣言には、クラスのかわりにenumキーワード(先頭小文字)を使います。
以下CupSize.javaというサンプルコードを見てください。
イメージとしては、コーヒーショップでカップのサイズが4つある(4つしかない)ということを表現したいとします。
定数なのですべて大文字で表記します。また、要素名はカンマで区切って記述します。
通常のクラスはインスタンスを作成する際にnew演算子を使いましたが、Enumでは使いません。
以下はサンプルです。
<結果を表示する>
GRANDE
Enumはデフォルトでメソッドをいくつか持っています。
以下で説明しているvaluesメソッドは、Enumであれば宣言・実装をしなくても使えます。
拡張for文と組み合わせて次のようなコードを書くことができます。
<結果を表示する>
SHORT
TALL
GRANDE
VENTI
このようにvaluesメソッドを使えば全要素が配列として取得できるので、拡張For文の条件指定に使えます。
また、switch文の中でケースラベルに指定することができます。
Coffee クラスでCupSizeを使用してみます。
コーヒーカップのサイズごとに違った料金を返すようにtoStringメソッドをオーバーライドしています。
※今回のswitch文ではreturnしていますのでbreakはありません。
テストクラスを書いてみます。
<結果を表示する>
360円です
列挙された以外の要素(上記の例のCupSize.Large)は存在し得ないというところがEnumの良い点です。
また、スペルミスもIDEが教えてくれます。
これがEnumではなく、単なるStringだとしたらこうはいきません。
バグが入り込む余地が少なくなるわけです。
さらに、Enumには、固有のフィールドやメソッド、コンストラクタを持たせることも可能です。
以下のサンプルコードを見て下さい。
ポイントは以下の3点です。
- 値の後ろに()を付けてその中にフィールドの値を書く
- フィールドをprivate finalとしてコンストラクタ内での初期化を強制する
- フィールドの値にアクセスすためのgetterメソッドを作る
使用例を以下Example11.javaで示します。
<結果を表示する>
SHORT:240
TALL:350
GRANDE:470
VENTI:590
以上、駆け足でEnumを見てきました。
<まとめ:隣の人に正しく説明できたらチェックを付けましょう>
□今現在を表すインスタンスはLocalDateTimeクラスのnowメソッドで取得できる
□日付の書式を指定するには、クラスDateTimeFormatterを使う
□Enum型は複数の定数をひとつにまとめることが出来る型のことである
□定数と異なり、Enumには固有のフィールドやメソッド、コンストラクタを持たせることも可能である
まとめができたら、アウトプットとして演習問題にチャレンジしましょう。
【今回の復習Youtube】
JavaSE8の解説に戻る
最後までお読みいただきありがとうございました。