Java:如何基于输入#2引用类var

时间:2013-10-15 03:30:51

标签: java string class parameters concatenation

我有一个混合了布尔和整数的类:

class Soup {
    boolean mItem1 = false
    boolean mItem2 = false
    int     mItem3 = 10
    boolean mItem4 = false
    int     mItem5 = 100 
{

我还有一个方法“void addIngredient(String itemName)”,我将传递一个字符串值,如“Item1”或“Item4”。

void addIngredient(String itemName) {
    // I need help with the following line
    Soup.m(itemName) = true
}

如何设置变量Soup.mItem1的值,例如,WITHOUT使用if语句或开关。例如,我可能添加最多25或50个“mItems”变量,这些变量可以是布尔值或整数值。

我基本上想要使用Soup.m并连接我传递的字符串(例如Item1)来创建字符串“Soup.mItem1”,然后设置一个值,例如“Soup.mItem1 = true”或“Soup”。 nItem3 = 1000“。

3 个答案:

答案 0 :(得分:0)

看一下这篇文章,讨论如何将作为参数或变量传入的字符串转换为字段。我认为这会奏效,但我还会做更多的研究:Creating a variable name using a String valueGet variable by name from a String

这就是我提出的:

final Map<String, boolean> itemType = new HashMap<>();

void addIngredient(String itemName) {
itemName="m" + itemName;
itemType.put(itemName, true);
}

认为这应该有用。

答案 1 :(得分:0)

您想使用reflection

import java.lang.reflect.Field;

public class Main 
{
    private boolean mItem1;
    private int mItem2;

    public static void main(String[] args)
        throws NoSuchFieldException, 
               IllegalArgumentException, 
               IllegalAccessException 
    {
        final Main instance;

        instance = new Main();
        instance.addIngredient("Item1");
        instance.setIngredientAmount("Item2", 1000);

        System.out.println(instance.mItem1);
        System.out.println(instance.mItem2);
    }

    public void addIngredient(final String itemName) 
        throws NoSuchFieldException, 
               IllegalArgumentException, 
               IllegalAccessException
    {
        final Class<Main> clazz;
        final Field       item;

        clazz = Main.class;
        item  = clazz.getDeclaredField("m" + itemName);
        item.set(this, true);
    }

    public void setIngredientAmount(final String itemName,
                                    final int    value)
        throws NoSuchFieldException, 
               IllegalArgumentException, 
               IllegalAccessException
    {
        final Class<Main> clazz;
        final Field       item;

        clazz = Main.class;
        item  = clazz.getDeclaredField("m" + itemName);
        item.set(this, value);
    }
}

我实际上不会推荐这个,但它应该满足你的要求。

答案 2 :(得分:0)

你可以用Reflection做到这一点,但是Reflection有很多警告,包括性能和代码的紧密耦合。所以,我建议不要使用Reflection,但如果必须,你可以这样做。

<强> OriginalClass

public class OriginalClass {
    public int var1;
    public String var2;
    public boolean var3;
}

主要

import java.lang.reflect.Field;
public class Main {
    public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
        OriginalClass orig = new OriginalClass();
        orig.var1 = 1;
        orig.var2 = "Hello";
        orig.var3 = true;
        for(int i = 0; i <= 3; i++) {
            Field origVar = OriginalClass.class.getDeclaredField("var" + i);
            System.out.println(origVar.get(orig));
        }
    }
}

或者,您可以使用getFields然后循环遍历所有字段。

for(Field origVar : orig.getFields())
    System.out.println(origVar.get(orig));

get()方法类似,set()上有Field方法。签名是

void set(Object obj, Object value);

注意:通常,由于封装,您的成员变量将被隐藏,因此您必须通过其getter和setter访问它们,如下所示。

Method m = OriginalClass.class.getDeclaredMethod("getVar1", null);
System.out.println(m.invoke(orig));
m = OriginalClass.class.getDeclaredMethod("setVar1", Integer.TYPE);
m.invoke(orig, 3);
System.out.println(orig.var1); //Will print 3