
7ステップで理解するJavaでの列挙型/enum使用法
株式会社ガリレオ
小山博史
2011/3/3
これからプログラミングを学習したい方、Javaは難しそうでとっつきづらいという方のためのJavaプログラミング超入門連載です。最新のEclipseとJava 6を使い大幅に情報量を増やした、連載「Eclipseではじめるプログラミング」の改訂版となります
“列挙”の使いどころは、定数の集合にあり
例えば、カレンダープログラムを作成したい場合は、1月から12月までをどのようにプログラム上で表現すればいいかを考える必要があります。トランプゲームを作成したい場合は、スーツ(スペード、ハート、ダイヤ、クラブ)について、同様に検討する必要があります。
こういった「あらかじめ要素数が分かっている定数の集合」を列挙して使うプログラムを作成するには、「列挙型(enumerated type)」の利用を検討するといいでしょう。
プログラムにおける列挙の表現方法はいくつかありますが、今回は「int enumパターン」「タイプセーフenumパターン」の紹介と、それらよりも使いやすい列挙型について順番に説明します。
EclipseでJavaプログラミングを始める準備がまだの方は、連載第1回の「Eclipse 3.4で超簡単Javaプログラミング基礎入門」で準備をしておいてください。
【Step 0】カレンダープログラムを考えてみる
まずは、簡単な機能を持つカレンダープログラムを自作することを想像してみてください。皆さんはどのように1年をプログラム上で表現するでしょうか。
一番単純な方法は、int型の値を使う表現ですから、1年の各月を表示するとしたら、次のようなプログラムを作ることになるはずです。
sample21/MonthList.javapackage sample21;
public class MonthList {
public void exec() {
for (int i = 1; i <= 12; i++) {
System.out.println(i + "月");
}
}
public static void main(String[] args) {
MonthList app = new MonthList();
app.exec();
}
}
実行結果
1月
2月
3月
4月
5月
6月
7月
8月
9月
10月
11月
12月
【Step 1】文字列の配列で表現してみる
数値そのままで実現できるような単純なプログラムの場合は、このように簡単に実装できますが、各月の名前を英語で表示したい場合は、どうでしょう。すぐに思いつくのは、文字列の配列を用意して表現する方法かと思います。
ただしJavaの配列では、添字が0から開始するので、その点に注意が必要です。以下のMonthInEnglishクラスでは、ある月が英語で何というかを表示しています。
sample21/MonthInEnglish.javapackage sample21;
public class MonthInEnglish {
private String[] months = new String[] {
"JANUARY", "FEBRUARY", "MARCH", "APRIL",
"MAY", "JUNE", "JULY", "AUGUST",
"OCTOBER", "SEPTEMBER", "NOVEMBER", "DECEMBER",
};
public void exec() {
System.out.println("2011年");
for (int i = 0; i < months.length; i++) {
String s = (i + 1) + "月";
System.out.println(s + ":" + months[i]);
}
}
public static void main(String[] args) {
MonthInEnglish app = new MonthInEnglish();
app.exec();
}
}
実行結果
2011年
1月:JANUARY
2月:FEBRUARY
3月:MARCH
4月:APRIL
5月:MAY
6月:JUNE
7月:JULY
8月:AUGUST
9月:OCTOBER
10月:SEPTEMBER
11月:NOVEMBER
12月:DECEMBER
【Step 2】Calendarクラスと「int enumパターン」
ところで、Javaにはカレンダーを表現するクラスは標準で備わってないのでしょうか。実は用意されていて、Javaでカレンダープログラムを作成する場合は、「java.util.Calendar」をよく使います。このクラスでは、月を表現する「JANUARY」などのstaticでfinalな変数が宣言されているので、これを使うこともできます。
実際の値は、「JANUARY」は0、「FEBRUARY」は1のようになっています。これらを使うと、例えば、次のようなプログラムが書けます。ここでは、2011年の各月に何日あるかまで表示しています。
sample21/JavaUtilCalendarMonthList.javapackage sample21;
import java.util.Calendar;
public class JavaUtilCalendarMonthList {
private String[] months = new String[] {
"JANUARY", "FEBRUARY", "MARCH", "APRIL",
"MAY", "JUNE", "JULY", "AUGUST",
"SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER",
};
public void exec() {
System.out.println("2011年");
for (int i=0 ; i<months.length ; i++) {
String s = (i+1) + "月";
switch (i) {
case Calendar.FEBRUARY:
s = s + ":" + months[i] + "(28日)";
break;
case Calendar.APRIL:
case Calendar.JUNE:
case Calendar.SEPTEMBER:
case Calendar.NOVEMBER:
s = s + ":" + months[i] + "(30日)";
break;
case Calendar.JANUARY:
case Calendar.MARCH:
case Calendar.MAY:
case Calendar.JULY:
case Calendar.AUGUST:
case Calendar.OCTOBER:
case Calendar.DECEMBER:
s = s + ":" + months[i] + "(31日)";
break;
}
System.out.println(s);
}
}
public static void main(String[] args) {
JavaUtilCalendarMonthList app = new JavaUtilCalendarMonthList();
app.exec();
}
}
実行結果
2011年
1月:JANUARY(31日)
2月:FEBRUARY(28日)
3月:MARCH(31日)
4月:APRIL(30日)
5月:MAY(31日)
6月:JUNE(30日)
7月:JULY(31日)
8月:AUGUST(31日)
9月:SEPTEMBER(30日)
10月:OCTOBER(31日)
11月:NOVEMBER(30日)
12月:DECEMBER(31日)■ finalで定数変数
ここで、finalについて説明しておきます。変数をfinalで修飾すると、その変数には一度だけ代入できます。
例えば、円周率の近似値を3.14として計算で使いたい場合は、PIという変数を用意して、そこへ3.14という値を設定したら変更したくないはずです。こういった変数を用意したいときに、次のように使います。
final double PI = 3.14;
ちなみに、このように、コンパイル時に定数となる式で初期化された基本データ(プリミティブ)型やjava.lang.String型のfinal変数を「定数変数(constant variable)」といいます。
■ 変数定数のオブジェクト状態は変更可能
参照型のオブジェクトをfinalで宣言された変数へ代入した場合は、注意が必要です。次のように用意した定数変数finalListに対して、新しいLinkedListのオブジェクトを代入できません。
つまり「finalList = new LinkedList<String>();」とするとエラーとなります。
final List<String> finalList = new LinkedList<String>();
// 次はコメントを外すとエラーとなる
// finalList = new LinkedList<String>();
// 次の文は可能
finalList.add("Java");
これは、finalListに代入された参照値は変更できないからです。しかし、finalListが参照しているオブジェクトの状態は変更できます。つまり、「finalList.add("Java");」のように要素を追加できます。
■ 「int enumパターン(int enum pattern)」
さて、列挙の話に戻りましょう。JavaUtilCalendarMonthListのように、staticでfinalな変数を使って値を列挙することにより、数値を使うよりもプログラムの可読性が良くなります。
こういった方法による列挙の表現は、「int enumパターン(int enum pattern)」といわれていて、よく使われています。
次ページでは、int enumパターンの問題点や「タイプセーフenumパターン」、そして「enum」キーワードと列挙型について解説します。
| Index | ||||||||
|
||||||||
【改訂版】Eclipseではじめるプログラミング バックナンバー 連載インデックスへ»
- 第1回 Eclipse 3.4で超簡単Javaプログラミング基礎入門
- 第2回 Javaで一から理解するプログラムの変数と演算子
- 第3回 プログラミングの醍醐味! Javaで“条件式”を理解する
- 第4回 プログラミングの真骨頂! Javaで“反復処理”を覚える
- 第5回 データ集合を扱うのに便利なJavaの配列と拡張for文
- 第6回 複雑なデータを表現できるクラスやフィールドって?
- 第7回 クラスの振る舞いを表すJavaの“メソッド”とは?
- 第8回 Javaの参照型を文字列操作で理解して文法を総復習
- 第9回 プログラムを「変更」しやすくする“インターフェイス”
- 第10回 Javaの実案件に必須のパッケージとインポートを知る
- 第11回 「static」でクラス共有の変数・メソッドを使いこなせ!
- 第12回 継承やオーバーライドで簡単にクラスを“拡張”しよう
- 第13回 “コンストラクタ”と初期化、本当に理解できてる?
- 第14回 再利用性の高いクラス作成に重要な“アクセス制御”
- 第15回 Javaは「抽象クラス」で実装を上手に再利用できる
- 第16回 “ネスト”した型で始める軽量Javaプログラミング!?
- 第17回 あなたの知らない、4つのマニアックなJava文法
- 第18回 強く型付けされているJavaの理解に必修の“型変換”
- 第19回 キュー構造をJavaで実装してジェネリック型を理解する
- 第20回 拡張for文の真の実力を知り、反復処理を使いこなせ
- 第21回 7ステップで理解するJavaでの列挙型/enum使用法
- 第22回 いまさら聞けない「Javadoc」と「アノテーション」入門
- 第23回 プログラマの宿命! 例外とエラー処理を理解する
- 第24回 Javaの例外処理で知らないと損する7つのテクニック
| Java Solution全記事一覧 |
TechTargetジャパン
- Scalaのパッケージ、アクセス修飾子、オブジェクト継承 (2012/5/22)
インポート、パッケージオブジェクト、抽象クラス/抽象メソッド、オーバーライド、final、シールドクラスなども - 基幹系システムでCloud SQLは使えるか試してみた (2012/5/17)
サンプルとしてMRPシステムを作成して動かし、「再帰呼び出し」などのパフォーマンスを測定して検証してみます - アジャイル管理ツール9選+Pivotal Tracker入門 (2012/5/14)
群雄割拠のアジャイルプロジェクト管理ツールを9つ紹介し、特に注目を集めているPivotal Trackerの基本的な使い方を解説します - サーバサイドJSやJavaでWebアプリが作れるXPages (2012/5/11)
Notes/Dominoの資産をサーバサイドJavaScriptやJavaで操作し、HTMLやJavaScript、CSSをUIにできる技術を紹介
|
|
キャリアアップ
スポンサーからのお知らせ
- - PR -
イベントカレンダー
- - PR -
