列挙型
列挙型はJDK5から追加された機能で、特定の値のみ持つクラスです。
クラスですから参照型となります。
通常、定数はfinal修飾子を付けた単独の変数ですが、これを使用することにより複数の定数をまとめて管理することができます。
定数以外のインスタンスを作成できないので、誤って異なる値が入る可能性がありません。
クラスやインターフェースと同様に単独で定義することもできれば、クラス内にメンバとして定義することも可能です。
ただしメソッド内にローカルインナークラスのように定義をすることはできません。
また1つのソースファイルの中に、複数の列挙型を定義することができます。
その場合、publicな列挙型は1つのソースファイルに1つしか定義できず、ソースファイル名と同じ名前にする必要があります。
1つのクラス内であれば、publicな列挙型は複数あっても構いません。
上図では、Season.javaファイル内にpublicな列挙型(enum)がSeasonというソースファイルと同じ名前で記述されています。
Sampleクラスではpublcな列挙型MonthとWeekがメンバとして定義されています。
列挙型の定義
[修飾子] enum 列挙型名{値1, 値2, 値3 ・・・}
列挙型を定義するには、enumキーワードを使用し、{ }内に定数をカンマ区切りで指定をします。
【列挙型の定義】
public enum Season { SPRING, SUMMER, AUTUMN, WINTER }
Season.javaファイルにpublicな列挙型を定義しています。
名前はファイル名と同じSeasonです。
値として、SPRING, SUMMER, AUTUMN,WINTERの4つを定義しています。
列挙型の利用
列挙型は参照型ですから、これを利用するにはインスタンス化する必要があります。
列挙型のインスタンス化は通常のクラスのインスタンス化とは異なりnewキーワードは使わず、次のように記述します。
列挙型名 変数 = 列挙型名.値
列挙型の要素ごとに上記の指定をします。
列挙型のインスタンス化
public class Enum1 { public static void main(String[] args) { Season s = Season.SPRING; switch (s) { case SPRING: System.out.println("春です"); break; case SUMMER: System.out.println("夏です"); break; case AUTUMN: System.out.println("秋です"); break; case WINTER: System.out.println("冬です"); break; } } }
実行結果
春です
3行目で列挙型Seasonに定義されているSPRINGを使用するために、インスタンス化をしています。
newキーワードは利用してないことを確認しましょう。
switch文の式として列挙型を指定できます。
case式で、SPRINGである場合の処理を定義しています。
列挙型のクラス内に用意されている主なメソッド
列挙型は、java.lang.Enumというクラスで定義されています。このクラスには、暗黙的に、
列挙型[] static values()
というメソッドは列挙型で定義された値を列挙型の配列で返します。
列挙型の要素の取り出し
public class Enum2 { public static void main(String[] args) { for(Season s : Season.values()){ System.out.println(s); } } }
実行結果
SPRING SUMMER AUTUMN WINTER
3行目の拡張for文内で、列挙型の値を配列として取り出すvalues()メソッドが使用されています。
values()メソッドはstaticなメソッドなので、Season.values()(列挙型名.メソッド名)と記述されています。
配列として取り出された要素を1つずつSeasong型の変数sに格納しながら、出力処理をしています。
列挙型にコンストラクタを定義
列挙型のクラス内にコンストラクタやメソッドを定義できます。
列挙型にコンストラクタとメソッドを定義する
public class Enum3 { enum Season{ SPRING("春"),SUMMER("夏"),AUTUMN("秋"),WINTER("冬"); private String kanji; Season(String k){ kanji = k; } public String getKanji(){ return kanji; } } public static void main(String[] args) { for(Season s : Season.values()){ System.out.println(s + ":" + s.getKanji()); } } }
実行結果
SPRING:春 SUMMER:夏 AUTUMN:秋 WINTER:冬
これまでは列挙型を外部のクラスとして登録し、main()メソッドのあるクラスから使用するという形をとっていましたが、この例ではEnum4というクラス内に1つのメンバとして列挙型を定義しています(2行目~14行行目)。
そしてその列挙型の中に、コンストラクタ(6行目~8行目)とコンストラクタで取り出すkanjiフィールドのゲッターメソッド(10行目~12行目)を定義しています。
3行目の列挙型の値の定義では、それぞれの値の後ろに()を記述してコンストラクタが呼びされたときに渡される値(春、夏といった漢字)を指定しておきます。
main()メソッドの16行目の拡張for文内の処理で、Season.values()で列挙型の配列を取り出す際に、6行目~8行目のコンストラクタが呼び出され、列挙型の各要素に定義された引数(春、夏、秋、冬)も同時にインスタンス化されます。
17行目では各Season型の変数sに格納された列挙型の値とともに、getKanji()メソッドで取り出された漢字が表示されます。
まとめ
列挙型
- 複数の定数をまとめて管理できる仕組みです。
- 定数以外のインスタンスを作成できないので、誤って異なる値が入る可能性がありません。
- クラスやインターフェースのように単独で定義できます。
- クラス内でメンバ変数として定義できます。
- メソッド内では定義できません。
- emumキーワードを使用して定義します。
- 1つのソースファイルに複数定義することができます。
- publicな列挙型は1つのソースファイルに1つしか定義できず、ソースファイル名と同じ名前にしなければなりません。
- クラス内の定義であれば、publicな列挙型は複数あっても良いです。
列挙型の利用
- staticなvalues()は、列挙型の要素を配列で返します。
- 列挙型内にコンストラクタやメソッドをていぎできます。
独学で挫折しそうになったら、オンラインプログラミングスクール