17

次の行に沿ってJavaで何かを実装しようとしています:

class Foo{
 private int lorem; //
 private int ipsum;      

 public setAttribute(String attr, int val){
  //sets attribute based on name
 }

 public static void main(String [] args){
  Foo f = new Foo();
  f.setAttribute("lorem",1);
  f.setAttribute("ipsum",2);
 }

 public Foo(){}
}

...変数は、変数名をハードコーディングせず、他のデータ構造を使用せずに、変数名に基づいて設定されます。これは可能ですか?

4

6 に答える 6

34

リフレクションを使用して実装する方法は次のsetAttributeとおりです (関数の名前を変更しました。フィールド タイプごとに異なるリフレクション関数があります)。

public void setIntField(String fieldName, int value)
        throws NoSuchFieldException, IllegalAccessException {
    Field field = getClass().getDeclaredField(fieldName);
    field.setInt(this, value);
}
于 2008-11-09T22:22:54.257 に答える
5

一般に、Reflection を使用します。これは、例を含むトピックの優れた紹介です

特に、「フィールドの値を変更する」セクションでは、やりたいことを実行する方法について説明しています。

著者は、「この機能は非常に強力であり、他の従来の言語に相当するものはありません」と言っていることに注意してください。もちろん、過去 10 年間 (記事が書かれたのは 1998 年) で、動的言語が大きく進歩したのを見てきました。上記は、Perl、Python、PHP、Ruby などでかなり簡単に実行できます。これは、「eval」タグに基づいてあなたが来たかもしれない方向だと思います。

于 2008-11-09T22:17:06.437 に答える
4

また、リフレクションを使用する複雑さの一部を隠すことができるBeanUtilsを見てください。

于 2008-11-09T22:21:26.193 に答える
3

質問はintに固有のものであり、これは役に立ちますが、ここではもう少し一般的なものです。Stringこのタイプのメソッドは、フィールド名とフィールド値のペアの表現でロードする場合に便利です。

import java.lang.reflect.Field;

public class FieldTest {

    static boolean isValid = false;
    static int count = 5;

    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        FieldTest test = new FieldTest();
        test.setProperty("count", "24");
        System.out.println(count);
        test.setProperty("isValid", "true");
        System.out.println(isValid);
    }

    public void setProperty(String fieldName, String value) throws NoSuchFieldException, IllegalAccessException {
        Field field = this.getClass().getDeclaredField(fieldName);
        if (field.getType() == Character.TYPE) {field.set(getClass(), value.charAt(0)); return;}
        if (field.getType() == Short.TYPE) {field.set(getClass(), Short.parseShort(value)); return;}
        if (field.getType() == Integer.TYPE) {field.set(getClass(), Integer.parseInt(value)); return;}
        if (field.getType() == Long.TYPE) {field.set(getClass(), Long.parseLong(value)); return;}
        if (field.getType() == Float.TYPE) {field.set(getClass(), Float.parseFloat(value)); return;}
        if (field.getType() == Double.TYPE) {field.set(getClass(), Double.parseDouble(value)); return;}
        if (field.getType() == Byte.TYPE) {field.set(getClass(), Byte.parseByte(value)); return;}
        if (field.getType() == Boolean.TYPE) {field.set(getClass(), Boolean.parseBoolean(value)); return;}
        field.set(getClass(), value);
    }

}
于 2015-05-18T18:16:39.387 に答える
1

使用状況に応じて、上記のアドバイスに従ってリフレクションを使用できます。または、おそらく HashMap の方が適しています...

于 2008-11-10T09:43:49.247 に答える
-1

作業中にリフレクション データの一部をキャッシュしたい場合があります。

import java.lang.reflect.Field;
import java.util.HashMap;

class Foo {
    private HashMap<String, Field> fields = new HashMap<String, Field>();

    private void setAttribute(Field field, Object value) {
        field.set(this, value);
    }

    public void setAttribute(String fieldName, Object value) {
        if (!fields.containsKey(fieldName)) {
            fields.put(fieldName, value);
        }
        setAttribute(fields.get(fieldName), value);
    }
}
于 2008-11-09T23:16:14.553 に答える