【问题标题】:SWT and Java 8 lambdas (Runnable and timerExec)SWT 和 Java 8 lambda(Runnable 和 timerExec)
【发布时间】:2018-01-23 23:37:36
【问题描述】:

我正在重构我前一段时间从事的一个 SWT 项目,我想使用 Java 8,现在在当前版本中,我有这样的东西:

       Runnable runnable = new Runnable() {
            public void run() {
                // do some stuff...
                Display.getCurrent().timerExec(1000, this);
            }
        };
       Display.getCurrent().timerExec(1000, runnable);

我正在尝试使用 Java 8,如下所示:

       Runnable runnable2 = () -> { 
            // do some stuff...
            Display.getCurrent().timerExec(1000, this);
        };
        Display.getCurrent().timerExec(1000, runnable2);

问题出在:

Display.getCurrent().timerExec(1000, this);

第一个代码(不是J​​ava 8)中的“this”是指可运行对象,第二个是指主类,实际上我在编译时得到的错误如下:

Display类型中的timerExec(int, Runnable)方法不是 适用于参数(int,MainClass)

如何解决这个问题,以便执行计时器?

编辑: 查看 StackOverflow 以前的问题,我发现:Lambda this reference in java

似乎无法在 lambda 中引用“this”,所以我不能将 SWT 计时器与 lambda 一起使用?有解决办法吗?

【问题讨论】:

  • 我能想到一个 hack,但它并没有真正节省那么多代码(这似乎是首先使用 lambda 的重点?),并且使用匿名类是更清楚地传达你正在做的任何方式。
  • Jorn,是的,我知道,在可运行文件中,我还有其他使用 lambda 的代码,如果可能的话,我希望所有内容都对齐。现在我很好奇,您能否提供破解以了解任何可能性?
  • 这个:ideone.com/FKNRJR 但是现在我再看一遍,它实际上使用了几个更多个字符。
  • 谢谢,但我觉得它真的很难看...

标签: java lambda swt


【解决方案1】:

我不确定你为什么要在 lambda 中进行自我引用。保持 lambda 表达式简短易读通常是一个好习惯。只需像这样从您的 lambda 调用私有方法:

Display.getCurrent().timerExec( 1000, () -> process() );

private void process(){
    // do some stuff...
    Display.getCurrent().timerExec( 1000, () -> process() );
}

【讨论】:

  • 这里的问题是 SWT 计时器就是这样工作的,所以外部调用只执行一次 Runnable,而 Runnable 内部的调用每次都重新执行它......你可以找到一个最小的例子在这里,不使用 Java 8:java2s.com/Tutorial/Java/0280__SWT/Createonerepeatingtimer.htm
  • 除非 Display.timerExec 要求用户传递相同的 Runnable 实例(根据他们的 javadoc,我认为不是这种情况),否则您可以使用私有方法重写您链接的代码。
  • 嗯嗯。我认为你是对的,我是 Lambda 新手,所以我正在学习,我现在无法测试它,但我会尽快做,如果它有效,我认为这是迄今为止最好的解决方案...... ;)
  • 我认为对于我个人的情况,这是更优雅和可读的解决方案,谢谢。
【解决方案2】:

如果您将 Runnable 声明为局部变量,则无法从 lambda 中引用 self Runnable 实例。

但是,如果您将 Runnable 声明为类的属性,则可以从 lambda 中引用 Runnable 实例:

class SomeClass {

    private Runnable runnable2 = () -> { 
        // do some stuff...
        Display.getCurrent().timerExec(1000, this.runnable2);
    };
}

你是唯一知道是否值得尝试这种方法的人......

【讨论】:

  • 我认为这是更优雅的解决方案,更一般地说,但在我的具体情况下很糟糕...... ;)
【解决方案3】:

这是一种“解决方法”,但它使事情不如原始代码清晰。我会保留原件。

    Runnable[] runnable2 = {null}; 
    runnable2[0] = () -> { 
        // do some stuff...
        Display.getCurrent().timerExec(1000, runnable2[0]);
    };
    Display.getCurrent().timerExec(1000, runnable2[0]);

【讨论】:

  • 我给你 +1 是因为它一点也不优雅,但对我来说听起来就像:“去他妈的系统!” :) 哈哈!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-08
  • 1970-01-01
  • 1970-01-01
  • 2017-12-01
  • 1970-01-01
  • 2018-06-02
  • 1970-01-01
相关资源
最近更新 更多