在 Java 中按名称设置变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/276555/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Setting variables by name in Java
提问by Mat Kelly
I'm looking to implement something in Java along the lines of:
我希望在 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(){}
}
...where a variable is set based on the variable name without the variable names hard-coded and without using any other data structures. Is this possible?
...根据变量名设置变量,没有硬编码的变量名,也没有使用任何其他数据结构。这可能吗?
采纳答案by Chris Jester-Young
Here's how you might implement setAttribute
using reflection (I've renamed the function; there are different reflection functions for different field types):
以下是setAttribute
使用反射实现的方法(我已重命名该函数;不同的字段类型有不同的反射函数):
public void setIntField(String fieldName, int value)
throws NoSuchFieldException, IllegalAccessException {
Field field = getClass().getDeclaredField(fieldName);
field.setInt(this, value);
}
回答by Greg Hewgill
In general, you want to use Reflection. Here is a good introduction to the topic with examples
In particular, the "Changing Values of Fields" section describes how to do what you'd like to do.
特别是,“更改字段的值”部分描述了如何做您想做的事情。
I note that the author says, "This feature is extremely powerful and has no equivalent in other conventional languages." Of course, in the last ten years (the article was written in 1998) we have seen great strides made in dynamic languages. The above is fairly easily done in Perl, Python, PHP, Ruby, and so on. I suspect this is the direction you might have come from based on the "eval" tag.
我注意到作者说,“这个功能非常强大,在其他传统语言中是没有的。” 当然,在过去十年中(这篇文章写于 1998 年),我们已经看到动态语言取得了长足的进步。上面的操作在 Perl、Python、PHP、Ruby 等中很容易完成。我怀疑这是基于“eval”标签的你可能来自的方向。
回答by toolkit
回答by Frank Krueger
You might want to cache some of the reflection data while you're at it:
您可能希望在使用时缓存一些反射数据:
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);
}
}
回答by PhiLho
Depending on the usage, you can use reflection as advised above, or perhaps a HashMap would be better suited...
根据使用情况,您可以按照上面的建议使用反射,或者 HashMap 可能更适合...
回答by Brian Risk
The question is specific to ints, which is helpful, however here is something a bit more general. This type of method is useful if you are loading in String
representations of field name / field value pairs.
这个问题特定于整数,这很有帮助,但这里有一些更笼统的东西。如果您正在加载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);
}
}