【问题标题】:how can I pass a variable into a new Runnable declaration? [duplicate]如何将变量传递给新的 Runnable 声明? [复制]
【发布时间】:2011-05-16 21:13:59
【问题描述】:

我有以下:

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

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

runOnUIThread(done);

然后我打电话给它。但是,我希望 "Hello" 不被硬编码,所以我可以将它传递进去。否则我必须为我想要打印的每个字符串都有这些声明之一。

(这实际上是一个 android 问题,但将其简化为基本 Java,因此更容易回答)

谢谢

【问题讨论】:

    标签: java android runnable android-2.1-eclair


    【解决方案1】:
    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 。信息) } }); } 你会有一个错误。
    • @gtoknu 然后将参数 e 设为最终
    • 将参数设置为最终参数会有什么不同吗?请进一步解释!我考虑过重写没有最终参数的方法,我应该调用另一个接收最终参数的方法并执行第一个方法会做什么?
    • @Gtoknu 除非我错了,否则您可以在覆盖或实现时更改参数的确定性,因为它不是方法契约的一部分,只是方法主体内的变量。即使你不能,你也可以这样做final Event ee = e;
    • 嗯,很高兴知道。我认为我的 C++ 经验困扰着我。因为在那里,如果您将函数参数的指针发送到类似 runnable 以在另一个线程中运行,则指向的数据可能会被破坏,并且您将收到访问无效内存的运行时错误。
    【解决方案2】:

    在 Java 中(我相信在 Android 中也是如此),您可以使用匿名内部类,就像 Bart van Heukelom 所建议的那样。 该方案的优点是代码少,可以访问外部类的字段和方法。

    但它有两个缺点:

    • 变量“hello”必须是final,

    • 匿名类有一个对外部类实例的内部引用——这意味着外部类被保留,否则它有资格进行垃圾回收。 @See: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); 
      }
    ...
    }
    

    【讨论】:

    • 是否有一个多线程解决方案,其中message 不必是最终的?
    • 本示例中的final 语句不是必需的。 - 但是当你同时在多线程中使用Runable时,你必须处理并发问题!
    猜你喜欢
    • 2014-02-09
    • 2012-04-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-21
    • 2017-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多