質問
私は、次の行に沿って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(){}
}
...ここで、変数は、ハードコーディングされた変数名なしで、他のデータ構造を使用せずに変数名に基づいて設定されます。これは可能ですか?
解決
リフレクションを使用して setAttribute
を実装する方法を次に示します(関数の名前を変更しました。フィールドタイプごとに異なるリフレクション関数があります):
public void setIntField(String fieldName, int value)
throws NoSuchFieldException, IllegalAccessException {
Field field = getClass().getDeclaredField(fieldName);
field.setInt(this, value);
}
他のヒント
通常、Reflectionを使用します。以下は、トピックと例
特に、「フィールドの値の変更」セクションでは、やりたいことを行う方法について説明します。
著者は、「この機能は非常に強力であり、他の従来の言語には同等のものがない」と述べていることに注意してください。もちろん、過去10年間(この記事は1998年に執筆されました)に、動的言語で大きな進歩が見られました。上記は、Perl、Python、PHP、Rubyなどでかなり簡単に実行できます。これは、「評価」に基づいてあなたが来たかもしれない方向だと思う。タグ。
また、 BeanUtils をご覧ください。あなた。
質問は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);
}
}
使用方法に応じて、上記のようにリフレクションを使用できます。そうでない場合は、HashMapの方が適しています...
リフレクションデータの一部をキャッシュしておきたい場合があります:
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);
}
}
所属していません StackOverflow