2008-11-09 116 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); 
    } 

}