- ベストアンサー
Enum 列挙型でお聞きします。
Enum 列挙型でお聞きします。 一般的に、列挙型の使用度はどのくらいがベストなのでしょうか? あまり使用しない方がいいものなのでしょうか? たとえば、データベースにかきこまれているカラム名をEnumの列挙型で指定しようとした場合、 これはやるべきではないのでしょうか? やはり、最初から、確実に決められていないとだめなのでしょうか? どうもいまいち、よくわかりません。 参考URLは、 http://www.stackasterisk.jp/tech/java/jdk506_01.jsp#2_1を参考にしています。 よろしくおねがいします。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
fswmiyajimさんのサンプルコードをコンパイルしそれを逆コンパイル(jadという野を使えばできます)したソースです↓ final class Columns extends Enum { private Columns(String s, int i, String columnName) { super(s, i); this.columnName = columnName; } public String getColumnName() { return columnName; } public static Columns[] values() { Columns acolumns[]; int i; Columns acolumns1[]; System.arraycopy(acolumns = ENUM$VALUES, 0, acolumns1 = new Columns[i = acolumns.length], 0, i); return acolumns1; } public static Columns valueOf(String s) { return (Columns)Enum.valueOf(Columns, s); } public static final Columns KEY; public static final Columns VALUE; private String columnName; private static final Columns ENUM$VALUES[]; static { KEY = new Columns("KEY", 0, "KEY"); VALUE = new Columns("VALUE", 1, "VALUE"); ENUM$VALUES = (new Columns[] { KEY, VALUE }); } } 1.privateのコンストラクタが自動で追加 2.KEYとVALUEはpublic static finalでクラス変数としてある 3.staticイニシャライザの中でKEYとVALUEのインスタンスを生成している 4.インスタンスの配列を作成し、staticイニシャライザ内でインスタンスを格納 などをしていることがわかると思います。 ちなみにstaticイニシャライザというのがクラスの初期化時に1度だけよばれるものです。 javaのenumの場合コンストラクタは必ず自動的にprivateになるので、クラス外からはインスタンスを生成できません。同じ名前のインスタンスがいくつもあってもenumとして意味がなく、メモリの無駄だからです。
その他の回答 (2)
- hoge_piyo
- ベストアンサー率57% (15/26)
Enumとほぼ同じ用なクラスは作成しようと思えばできます。以下のURLのJava魂という本の7章に詳しく書かれています。 http://www.amazon.co.jp/Java%E9%AD%82%E2%80%95%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%82%92%E6%A5%B5%E3%82%81%E3%82%8B%E5%8C%A0%E3%81%AE%E6%8A%80-Robert-Simmons-Jr/dp/4873112079 簡単にいうとコンストラクタはすべてprivateにしておいて、インスタンスはstatic finalでクラスの初期化時に作成してしまうという方法です。(なおかつそのためのユーティリティクラスを作っておいて、それを継承して作成するようにする) 上記のやり方と、enumを使用した場合の違いとしては、 まず利点としては、switch文で使えるということや、EnumMapで使用できるなどです。switchはif elseの繰り返しよりもパフォーマンス的に有利ですし、同じくEnumMapもHashMapよりはやくなります。 一方欠点としては、継承ができないと言う点、また記述が若干冗長になる点でしょうか。 ただenumも自由にメソッドは追加できたり、インターフェイスは実装できるので、継承ができなくてもそんなに困ることはありません。 質問にある、データベースにかきこまれているカラム名に関してですが、Enumにしてもしなくてもどちらでもいいと思います。ただ、多くの箇所にでてくるのなら、Stringをリテラルで書くのではコンパイル時にミスがチェックできないので、何らかの形で参照するようにしたほうがよいとは思いますが。
- fswmiyajim
- ベストアンサー率50% (2/4)
回答になるか不安ですが・・・ enumは要素毎に任意の値で初期化された属性を持つ事ができます。 ご参考にされたページでは存在に触れる程度で端折られていますが、 enumには引数付きコンストラクタを定義できます。 それを使う事で、定義内に初期値を記述してやる事が可能です。 例えば、以下の例では文字列型の属性を定義し、初期値を設定しています。 enum Columns { KEY("KEY"), VALUE("VALUE"); private String columnName; private Columns(String columnName) { this.columnName = columnName; } public String getColumnName() { return this.columnName; } } 尚、初期化されるタイミングについてですが、 enumのコンストラクタは当該enumが最初にアクセスされた時に、全ての要素から一斉に呼ばれます。 javaのenumの要素は静的な不変オブジェクトだからです。
補足
解答ありがとうございます。 このとき、コンストラクタは、 どうよびだすものなのでしょうか? Columns com = new Columns("teest"); と設定するわけではないのでしょうか? 試したところ、errorがでました。 > 尚、初期化されるタイミングについてですが、 enumのコンストラクタは当該enumが最初にアクセスされた時に、全ての要素から一斉に呼ばれます。 javaのenumの要素は静的な不変オブジェクトだからです つまり、たとえばColumns.Keyにアクセスしたとき、コンストラクタが実行される、という事でしょうか? よろしくおねがいします。