如何使Runnable更改给定值

时间:2013-10-04 20:17:27

标签: java runnable

所以我目前面临的问题是我想编写一个方法,创建一个可以改变给定值的runnable;在这种情况下,它是一个布尔对象。

(我使用它,以便能够以不同的方式做出反应 到按键)

如果我只使用传递的Object的方法,它就可以正常工作。

然而:

public static Runnable createOnOffSwitchRunnable(Boolean b)
{
    final Boolean Reference = b;
    Runnable R = new Runnable()
    {
        public void run()
        {
            if (Reference.booleanValue() == true)
            {
                Reference = false;
            }
        }
    };
    return R;
}

显然这是工作,因为我不能直接为最终变量赋值,而布尔对象没有“set”-method。但是我需要声明它是最终的,甚至可以创建Runnable。

那么如何使用runnable更改传递的值? (如果我能继续使用标准的Java类型而不是“发明”一些新类,那将是很好的)

如果是这样,是否有保存和传递方法的替代方法?

任何帮助将不胜感激(:

3 个答案:

答案 0 :(得分:4)

你可以使用这个技巧,尽可能接近你的意图:

public static Runnable createOnOffSwitchRunnable(final Boolean... b) {
    return new Runnable() {
        public void run() {
            if (b[0].booleanValue()) {
                b[0] = false;
            }
        }
    };
}

我做了以下事情:

  • 将参数设为final,而不是创建单独的最终局部变量
  • 创建了参数varags,它实际上是方法内部的一个数组,但调用者可以使用一个布尔参数调用,因此签名对于这种情况看起来是相同的
  • 参数 array 是final,但其内容不是 - 这就是“技巧”
  • 简化了逻辑:: testing booleanValue==true是一个反模式,只是测试booleanValue本身
  • 返回Runnable而不创建(不必要的)本地变量

答案 1 :(得分:3)

您调用Reference的局部变量仅在createOnOffSwitchRunnable运行时存在,并在返回时消失;修改它没有任何意义。如果在您的情况下有意义,您可以修改实例变量。如果这样做,你应该声明变量volatile以防止陈旧的读取(也称为"the law of the blind spot")。

volatile Boolean Reference;

public static Runnable createOnOffSwitchRunnable(Boolean b)
{
    Reference = b;

    Runnable R = new Runnable()
    {
        public void run()
        {
            if (Reference.booleanValue() == true)
            {
                Reference = false;
            }
        }
    };
    return R;
}

另一个选择是在Runnable中使Reference成为实例变量。这也可以解决你的问题,我不知道你要做什么。

public static Runnable createOnOffSwitchRunnable(final Boolean b)
{

    Runnable R = new Runnable()
    {
        private Boolean Reference = b;

        public void run()
        {
            if (Reference.booleanValue() == true)
            {
                Reference = false;
            }
        }
    };
    return R;
}

(另外,请使用标准命名约定,写成标题案例Reference看起来像是一个类的名称。)

答案 2 :(得分:1)

使用AtomicBoolean。它具有线程安全的优点。