- PR -

フィールドのデータを動的に取得したい

投稿者投稿内容
unagi2000
会議室デビュー日: 2007/02/28
投稿数: 7
投稿日時: 2007-07-26 16:52
皆様お世話になります。

以下のように設定したフィールドfld1〜fld5までの値をfor文で取得したいのですが、
(リフレクションを使ってトライはしましたが・・)方法がよく分かりません。

配列でデータを取り扱えれば良いのですが、
既に作成されたクラスを利用しなければならないので
何方かご教示をお願い致します。


public class Sample_FieldName {
private static void main(String[] args) {
String fld1 = "AA";
String fld2 = "BB";
String fld3 = "CC";
String fld4 = "DD";
String fld5 = "EE";

//以下のfor文は期待した結果にはなりませんが、
//フィールドfld1〜fild5に入れられたデータを
//AA
//BB
//CC
//DD
//EE
//の順にプリントアウトしたいです。
for(int i=1; i<6; i++){
System.out.println("fld" + i);
}
}
}
小僧
ぬし
会議室デビュー日: 2002/08/14
投稿数: 526
投稿日時: 2007-07-26 17:48
コード:

String[] strs = {fld1,fld2,fld3,fld4,fld5};

for(int i=0; i < strs.length; i++){
System.out.println("fld" + strs[i]);
}



じゃあダメでしょうか?。

mainメソッド内で定義した物はフィールドではなく、単なる自動変数ですよ。
本当はmainメソッドの外側で定義されているということならインスタンス
のフィールドなんですが。




[ メッセージ編集済み 編集者: 小僧 編集日時 2007-07-26 17:53 ]
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2007-07-26 19:48
ローカル変数の名前はランタイムで取得できません。
一定の条件を満たせばクラスファイルの中にはあるので
デバッガ用のAPIを使うということになると思いますが、
基本的には無理と諦めてください。

staticフィールドなら
コード:
for(Field f : Foo.class.getDeclaredFields()){
    f.setAccessible(true);
    f.get(null);
}


で取得できます。
unagi2000
会議室デビュー日: 2007/02/28
投稿数: 7
投稿日時: 2007-07-27 11:41
小僧様
かつのり様

お教え頂いたことを自分なりにまとめ直し、
下記の様なコードを作成したところ、
当初の目的を何とかクリアする事が出来ました。

有難う御座いました。
コード:
import java.lang.reflect.Field;

public class Sample_FieldName5 {
    public static void main(String[] args) {
        try{
            FLD cfld = new FLD();
            Class cfldClass = cfld.getClass();
            for(int i=1; i<6; i++){
                Field fld = cfldClass.getDeclaredField("fld" + i);
                System.out.println(fld.get(cfld));
            }
		
        }catch(Exception e){
            System.out.println(e.toString());
        }
    }
}


class FLD{
	String fld1 = "AA";
	String fld2 = "BB";
	String fld3 = "CC";
	String fld4 = "DD";
	String fld5 = "EE";
}



実行結果
AA
BB
CC
DD
EE
nagise
ぬし
会議室デビュー日: 2006/05/19
投稿数: 1141
投稿日時: 2007-07-27 13:15
既存クラスとの繋ぎということですが、リフレクションを使わずに途中にメソッドを噛ませる方が後のメンテナンス性はよいのではないでしょうか。

コード:
public String getValue(FLD fld, int index) {
  switch(index) {
    case 0:
      return fld.fld1;
    ...
  }
}
public void setValue(FLD fld, int index, String value) {
  switch(index) {
    case 0:
      fld.fld1 = value;
      return;
    ...
  }
}

小僧
ぬし
会議室デビュー日: 2002/08/14
投稿数: 526
投稿日時: 2007-07-27 14:41
素朴な疑問なんですが、リフレクションを使うほどの問題なのか?
と思います。既存クラスの形態は分からないですが、nagiseさんの
書いたコードや、コンストラクタで古いクラスを受けてラップする
アダプタクラスで対応した方が、メンテナンス性が高く後々触る
人にも思想が伝わりやすいコードになると思うんですが。
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2007-07-27 14:50
リフレクションを覚えた手の頃は面白がって色々やりましたね。
突き詰めると非常に面倒な処理でもあるんで、
極力避けるようになりましたが。
unagi2000
会議室デビュー日: 2007/02/28
投稿数: 7
投稿日時: 2007-07-27 16:00
nagise様
小僧様
かつのり様

お世話になっています。
リフレクションを使う意味というのは正直、スキルレベルが低いので判断出来ません。

ただ、リフレクションを使ったコーディングをしてみたのですが、
思っていた程、プログラムは楽になりませんでした。
可読性も落ちるような気はします。

勉強不足もあるのですが、
レガシーシステムの言語からJavaに直接書き直しているので、
美しくないこともアリ、という考えでやっています。

長々すみません。
nagiseさんのサンプルコード参考にさせて頂きます。
有難う御座いました。

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