- PR -

連番定数の宣言・使用方法に関して

投稿者投稿内容
マリン
常連さん
会議室デビュー日: 2006/05/28
投稿数: 41
投稿日時: 2007-05-10 14:26
CSV文字列を分解してString[]の結果を返してくれる既存メソッドがあります。
元のCSVの列定義は後から途中に列が追加されたりする可能性があるため、JavaではなくVC++で同じような処理を記述していたときにはenum型を使ってcsv[FIELD_NAME]のように参照するようにしていました。
コード:
private static final int IDX_FOO = 0;
private static final int IDX_BAR = 1;


今まではJ2SE1.4ベースで開発していたので上記のような方法を使っていましたが、途中に新たな定義を追加したい場合にそれ以降のインデックスを手作業でインクリメントしなくてはいけないので、マジックナンバーを使わないという観点ではとりあえず使えますがメンテナンス性があまりよくありません。
J2SE 5.0に乗り換えてEnum#ordinalを使用することも考えたのですが、対象CSVの列数が多く、なおかつ使用するのはその一部だけという場合にやはりVC++だと
コード:
typedef enum {
	IDX_COLUMNA = 0,
	IDX_COLUMNB,
	IDX_COLUMNY = 24,
	IDX_COLUMNZ,
} COLUMN;


といった宣言を使って実現していましたが、Enumクラスは単純な連番定数宣言ではないようですので…。
Javaでも同様に手軽(?)に連番定数を宣言・使用できる方法が何かありましたら教えてください。
mio
ぬし
会議室デビュー日: 2005/08/25
投稿数: 734
お住まい・勤務地: 神奈川県
投稿日時: 2007-05-10 16:16
Cのenumはintだし、同様に単純に書くことは、Javaではできないのでは。

Enumのコンストラクタで値を渡しておいて、toString()で返すとか?(^_^;
parseInt()せねばなりませんが。
nagise
ぬし
会議室デビュー日: 2006/05/19
投稿数: 1141
投稿日時: 2007-05-10 16:36
以下のようなこともできますが、根本解決かと言われると答えに窮します。
コード:
enum Hoge {
    HOGE,
    PIYO(3),
    ;

    int hoge;
    Hoge() {}
    Hoge(int hoge) {
        this.hoge = hoge;
    }
    public int getHoge() {
        return this.hoge;
    }
}

マリン
常連さん
会議室デビュー日: 2006/05/28
投稿数: 41
投稿日時: 2007-05-10 17:07
mio様、nagise様、ご回答ありがとうございます。

ではとりあえず定義する列が一部だけという使い方をしたい、という条件をなしとしたら「このメソッドは、ほとんどのプログラマにとって役に立ちません。」という記述があるものの、Enum#ordinalを使うのが一番お手軽な方法ということになるでしょうか…?
あまりこういう要件ってないのでしょうか?
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2007-05-10 17:24
ordinalはおすすめしません。
定義順でしかないため、リファクタリングなどで、
メンバーをソートしたとたんに破綻します。
sawat
大ベテラン
会議室デビュー日: 2006/08/02
投稿数: 112
投稿日時: 2007-05-10 17:31
nagiseさんのをちょっとだけ発展させて、
コード:
public enum SeqEnum {
	IDX_COLUMNA(0),
	IDX_COLUMNB,
	IDX_COLUMNY(24),
	IDX_COLUMNZ;

	private static int seq = 0;

	private int number;

	SeqEnum() {
		this.number = seq++;
	}

	SeqEnum(int i) {
		seq = i;
		this.number = seq++;
	}
	
	public int getNumber() {
		return number;
	}
	
	public static void main(String[] args) {
		for (SeqEnum e : SeqEnum.values()) {
			System.out.println(e + " : " + e.getNumber());
		}
	}
}


みたいにすれば、VC++のenumにより近くなりますね。

これも定義順に依存してますが…。
マリン
常連さん
会議室デビュー日: 2006/05/28
投稿数: 41
投稿日時: 2007-05-10 23:47
かつのり様、sawat様、ご回答ありがとうございます。

そういえばEclipseだと「メンバーのソート」なんて機能がありましたね。使ったことがなかったのですっかり忘れていました。でも私はAll-In-One-Eclipse 3.0.1を使っておりEclipse 3.2.0の開発環境なのですが、「メンバーのソート」ダイアログでは「フィールド、列挙型定数、およびイニシャライザーをソートしない」がデフォルトになっていましたし、「すべてのメンバーをソート」を選んだ際の警告メッセージとして列挙型がソートされる危険性に関しても表示されているのでいいかなぁ・・・なんて

逆にちょっと余談になりますが、「メンバーのソート」って皆さんよく使っているものなのでしょうか?私はデフォルトのキーバインドでCtrl+Oのクイックアウトライン機能からインクリメンタル検索したり、F3とAlt+Leftを使ってコードサーフィン(なんて単語ないか?)することが多いですし、データベースのテーブル構造を表現するpojoクラスなども別に作ってある仕様書の定義順になっていた方が可読性が高いので、ソース上で物理的(?)にメンバーをソートすることにあまりメリットを感じられないのですが…?

でもチーム開発において誰かが「メンバーのソート」をしてしまった際の不具合を防ぐためには、やはりJ2SE 1.4のときと同様にstatic final形式で宣言しておくのが(項目追加時に多少面倒であるとしても)一番安全でお手軽(?)ということになるでしょうか?

「列挙型」だけではなく「連番型」みたいなのがあるといいのかもしれませんね

[ メッセージ編集済み 編集者: マリン 編集日時 2007-05-11 00:22 ]
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2007-05-11 00:19
私の場合は同一プロジェクト内において、コードの品質を一定にする為に、
フォーマットとメンバーのソートは欠かせません。

どのソースを見てもメンバの並び順が一定だと落ち着きますよ。
どこにどんなメンバがあるか一発なので。

フィールドの初期化子もenumメンバと同様にソートの影響を受けるので、
フィールドの初期化子は全く使いません。
非staticの場合はコンストラクタで十分ですし、
staticの場合はstaticイニシャライザ節を使います。

Eclipseの3.3からは保存時にこれらのコード整形処理を自動実行することができます。

スキルアップ/キャリアアップ(JOB@IT)