通过上下文传递类名,并使用它来存储不同类中的静态值

时间:2011-06-17 04:27:31

标签: java class methods static closures

对话框和数组显示得很好,我只是希望能够在onClick中的原始类中设置静态变量,该变量位于不同类中的方法中。所有trycatch和。{ <?>是我在编译器的坚持下投入的东西:

public class Setter
    {
    public void myList(Context context, Class<?> thisclass, int arrayid, String choice)
        {
        return new AlertDialog.Builder(context)
        .setItems(arrayid, new OnClickListener()
            {
            @Override
            public void onClick(DialogInterface dialog, int which)
                {
                setChoice(thisclass, context, arrayid, which, choice);
                }
            })
        .create();
        }           
    public void setChoice(Class<?> thisclass, Context context, int arrayid, int which, String choice)
        {
        String[] array = context.getResources().getStringArray(arrayid);
        try
            {
            Field f = thisclass.getDeclaredField(choice);
            f.set(null, array[which]);
            }
        catch (SecurityException e)
            {
            e.printStackTrace();
            }
        catch (NoSuchFieldException e)
            {
            e.printStackTrace();
            }
        catch (IllegalArgumentException e)
            {
            e.printStackTrace();
            }
        catch (IllegalAccessException e)
            {
            e.printStackTrace();
            }
        }
    }

public class ClassA extends Activity
    {
    static String stringa;
    Setter setted = new Setter();
    ...
    public void onCreate()
        {
        super.onCreate();
        ...
        AlertDialog thinga = setted.myList(this, getclass(), R.array.thinga, stringa).show();
        ...
        }
    }

当我从列表中选择一个项目时,我从调试器中得到了这个:

ClassCache.findFieldByName(Field[], String) line: 438   
Class.getDeclaredField(String) line: 666    
Setter.setChoice(Class, Context, int, int, String) line: 45 // the line with the Field

我认为我错误地把它传给了我,但这有点超出了我目前的深度。

我有许多不同的课程,每个课程都有自己的static String个。我正在传递String(在choice)名称下方的方法,以及我希望的原始类调用方法调用方法导致的context下面的代码。我希望我可以拨打context.choice = something并且机器会将其读作ClassA.stringa = something;我该怎么做?

简单地说,我想要一个用户可以选择的项目列表作为对话的内容,并让他们的选择被保存并且可以被要求创建对话的类访问。也许我说这一切都错了,但我厌倦了处理其他涉及使用微调器做同样事情的'kludges'。

因为onClick不能在其他地方声明非最终对象(至少这是我的理解),我想也许我可以通过调用另一个方法setChoice来解决这个问题。所选择的任何价值。我肯定会说这是一个混合物,并希望能够了解你应该如何应对这些事情。

3 个答案:

答案 0 :(得分:1)

简短回答 - 使用the Reflection API

答案很长 - 您需要获得对所需上下文Class的{​​{3}}的访问权限。获得Field实例的访问权限后,您可以使用Fields方法设置其值; API调用有点棘手,因为你需要传入你希望修改其字段的对象引用(上下文对象而不是上下文类)。

方法的Contextchoicesomething参数必须包含必要的信息才能使此操作尽可能简单。换句话说,Context类可能必须包含包含该字段的实际Class对象(或提供获取方法的对象)。

答案 1 :(得分:1)

Java没有闭包,但你可以接近匿名的内部类。

String output;
public void onCreate() {
    Setter.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            output  = "selected";
        }
    });
}

另请参阅此摆动教程:http://download.oracle.com/javase/tutorial/uiswing/events/actionlistener.html

编辑: 根据你的例子,这应该是这样的:

public class Setter
{
public void setChoice(IsetString setter, String something)
    {
    setter.setString(something);
    }
}


class ClassA extends Activity implements setString
{
static String stringa;
string polka = "dots";
Setter setted = new Setter();
...
public void onCreate()
    {
    super.onCreate();
    ...
    setted.setChoice(new IsetString() {

        @Override
        public void setString(String s) {
            stringa = s;
        }
    }, polka);
    ...
    }
}

interface IsetString {
    void setString(String s);
}

答案 2 :(得分:0)

你可以使用反射。假设你的上下文是类本身

public void setChoice(Class<?> context, String choice, String something)
{
   try {
     Field f = context.getDeclaredField(choice);
     f.set(null, something);
   } catch (....) {
   }
}

添加适当的异常处理


请注意,set的第一个参数为null。这仅适用于静态方法。因此,您可能希望使用f.getModifiers()检查该方法是否为静态。