2008-11-09 109 views
11

我期待在Java中實現的線沿線的東西:通過設置變量名在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(){} 
} 

...其中一個變量是基於變量名稱設置不變量名稱硬編碼而不使用任何其他數據結構。這可能嗎?

回答

24

這裏是你會如何使用反射實現setAttribute(我已經改名功能;要爲不同的字段類型不同的反射功能):

public void setIntField(String fieldName, int value) 
     throws NoSuchFieldException, IllegalAccessException { 
    Field field = getClass().getDeclaredField(fieldName); 
    field.setInt(this, value); 
} 
5

一般來說,你想使用反射。 topic with examples

特別是,「更改字段值」部分介紹瞭如何執行您想要的操作。

我注意到作者說:「這個功能非常強大,並且在其他常規語言中沒有相同之處。」當然,在過去的十年裏(這篇文章是在1998年寫的),我們看到動態語言取得了很大的進展。上述內容在Perl,Python,PHP,Ruby等中很容易完成。我懷疑這是你可能來自「eval」標籤的方向。

+0

鏈接似乎被打破;( – Vlad 2013-03-31 14:52:55

+0

我已經固定的聯繫 – 2013-04-02 18:55:23

3

另外,看看BeanUtils它可以隱藏使用反射從你的一些複雜性。

0

你可能想緩存一些反射數據,而你「再在它:

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); 
    } 
} 
1

根據不同的使用情況,您可以使用反射如上建議,或者是一個HashMap會更適合...

1

這個問題是特定於整數,這是有幫助的,但是這裏有一些更一般的東西。如果您正在加載字段名稱/字段值對的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); 
    } 

}