如何将变量传递到新的Runnable声明中?

24

我有以下内容:

Runnable done = new Runnable()
    {
        public void run()
        {
            System.out.println("Hello");
        }
    };

然后在我的Android活动中,我会调用类似以下的内容:

runOnUIThread(done);

我随后调用了它。但是,我希望那个"Hello"不是硬编码的,所以我可以传递它。否则,每个我想打印的字符串都必须有一个这样的声明。

(实际上这是一个安卓问题,但我将其简化为基本的Java问题,以便更容易回答)

谢谢

2个回答

49
在Java中(我相信在Android中也是一样的),您可以使用匿名内部类,就像Bart van Heukelom建议的那样。这种解决方案的优点是可以少写一些代码,并且可以访问外部类的字段和方法。
但它有两个缺点:
- 变量“hello”必须是final。 - 匿名类具有对外部类实例的内部引用 - 这意味着当外部类本应被垃圾回收时,它仍然被保留。 参见:《Effective Java》[Joshua Bloch],条目22:静态成员类优于非静态成员类。
在我看来,用这种方式给类实例添加参数是不好的做法。
因此,我认为,只要您不需要访问外部类的方法和字段,最好编写一个特定的类来执行此任务,并将其作为静态成员类。
class Demo {
...

  private static class MyRunnable implements Runnable {
     private final String message;

     MyRunnable(final String message) {
       this.message = message;
     }

     public void run() {
       System.out.println(message);
     }
  }

  public void startThread() {
    MyRunnable myRunnable = new MyRunnable("Hello");

    runOnUIThread(myRunnable); 
  }
...
}

1
有没有一种多线程解决方案,其中 message 不必是最终的? - Someone Somewhere
这个例子中的final语句并不是必须的。- 但是当你同时在多个线程中使用Runable时,就必须处理并发问题! - Ralph

22
final String hello = whereverItsComingFrom;
Runnable done = new Runnable()
    {
        public void run()
        {
            System.out.println(hello);
        }
    };

不是最好的方式,因为如果你有像这样的东西:public void receivedEvent(Event e) { queueEvent(new Runnable() { public void run() { System.out.println(e.message) } }); }你会遇到一个错误。 - Gustavo Maciel
3
@gtoknu 那就把参数 e 设为 final。 - Bart van Heukelom
有final参数会有什么区别吗?请进一步解释!我考虑过重写没有final参数的方法,我应该调用另一个接收final参数的方法并执行第一个方法应该执行的操作? - Gustavo Maciel
除非我错了,当覆盖或实现时,您可以更改参数的最终性,因为它不是方法合同的一部分,而只是方法体内的变量。即使您不能,也可以使用“final Event ee = e;”来解决问题。 - Bart van Heukelom
1
嗯,好的知道了。我认为我的C++经验让我感到困扰。因为在那里,如果您将函数参数的指针发送到类似于可运行对象的东西以在另一个线程中运行,则指向的数据可能会被销毁,您将获得访问无效内存的运行时错误。 - Gustavo Maciel
'final'关键字在Java中不是公共API的一部分。在参数列表中使用'final'关键字意味着它在方法内部是不可变的;没有'final'关键字,该值可能会在方法执行期间发生更改,但这并不使其成为输入输出参数。https://dev59.com/72435IYBdhLWcg3wfgMf - andersoj

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接