【问题标题】:How can I suppress anonymous new runnable() can be replaced with lambda如何抑制匿名 new runnable() 可以替换为 lambda
【发布时间】:2015-08-28 00:30:20
【问题描述】:

我收到了“可以用 lambda 替换匿名新的 runnable()”警告,并使用以下代码。

final ScrollView sv = (ScrollView) findViewById(R.id.scrollView);
sv.post(new Runnable() {

    @Override
    public void run() {
        sv.fullScroll(ScrollView.FOCUS_DOWN);
    }
});

我在谷歌上搜索得很辛苦,似乎是用 lambda 表达式重写...

final ScrollView sv = (ScrollView) findViewById(R.id.scrollView);
Runnable test = () -> sv.fullScroll(ScrollView.FOCUS_DOWN);
test.run();

但是当我尝试运行应用程序时,Android Studio 停止并出现如下错误:

Error:(78, 40) error: lambda expressions are not supported in -source 1.7
(use -source 8 or higher to enable lambda expressions)

我不明白为什么 Android Studio 让我使用 lambda 表达式,即使它无法编译。是bug吗?

另外,我尝试使用gradle-retrolambda,但它很难用于biginner。

由于我无法编译我的代码,我不确定上面的 lambda 表达式是否正确。

在我看来,IDE 不应该抱怨代码无法编译。所以我认为应该禁止使用 lambda 表达式的警告。但是不知道怎么可能……

感谢任何帮助。

【问题讨论】:

  • 您使用哪个版本的 Android Studio?
  • 我用的是Ver.1.2.2最新版。

标签: java android lambda java-8


【解决方案1】:

这里似乎有一个新问题,Android Studio Arctic Fox 2020.3.1 Patch 3(当前版本)没有提供禁用导致警告的检查的方法 “匿名 [class] 可以替换为 lambda”。

因此,如果我想在没有警告的情况下进行编译,我必须用 lambdas 替换我所有的匿名类(我有很多),然后我无法使用 JDK 7 运行我的代码。

还有一个检查会导致警告“Lambda 可以被匿名类替换”,并且这个可以被禁用。

???!!!

【讨论】:

    【解决方案2】:

    通过谷歌搜索,发现安卓官方还不支持JDK8。 See this link

    虽然我们可以使用Retrolambda、(对于Android Studio,它是gradle-retrolambda)或RxJava,但它们只是一个FLAVOR ...

    我的问题是由安装JDK8引起的,而不是应该安装JDK7。
    本来以为还是安装JDK8比较好,因为oracle现在已经正式支持JDK8,已经终止更新JDK7了,但是想错了。

    我卸载JDK8并安装JDK7后,IDE没有警告使用lambda表达式,或者编译时没有出现lambda expression is not supported in -source 1.7错误。

    【讨论】:

      【解决方案3】:

      首先,正如您所说,“匿名新的 runnable() 可以替换为 lambda”是一个警告。虽然这样的警告不像编译器错误那么严重,但您仍然应该了解警告的原因,以便对如何处理它做出明智的决定。在这种情况下,警告来自 IDE,而不是编译器,可以安全地忽略。 Android Studio 应该有一个设置,您可以在其中禁用此警告,但我一直无法找到确切的方法。我将首先单击源代码中的 new Runnable() 文本,然后按 Alt-Enter 以查看快速修复选项。

      或者,如果您想在代码中使用 lambda 函数,则需要启用对 Java 8 的支持,因为您会收到错误消息。请注意,某些 Java 8 功能仅在您的应用以 Kit Kat 或更高版本为目标时可用。早期版本的 Android 支持 Lambda 函数,因此您不必担心这种情况。要为您的项目启用 Java 8,请将您的 build.gradle 文件修改为类似于以下内容:

      android {
          compileSdkVersion 19
          buildToolsVersion "19.0.0"
      
          defaultConfig {
              minSdkVersion 7
              targetSdkVersion 19
          }
      
          compileOptions {
              sourceCompatibility JavaVersion.VERSION_1_8
              targetCompatibility JavaVersion.VERSION_1_8
          }
      }
      

      重要的部分是compileOptions 闭包。剩下的就是给出它在文件中所属的上下文。

      请注意,我尚未对此进行编译和测试。另外,我不确定您是否需要sourceCompatibilitytargetCompatibility。我建议您进行一些研究和实验,以确定是否需要两者才能在您希望定位的设备上编译和运行您的应用程序。

      来源:

      How to set -source 1.7 in Android Studio and Gradle

      Java 8 features into Android Development

      【讨论】:

      • 这不是 lint 警告,更可能是 IDE 提示。
      • @assylias 感谢您的澄清。我希望 AS 更清楚它给出的任何消息的严重程度......或者我可能没有经常遇到这样的问题,以至于无法知道 AS 如何表示与实际编译器错误的区别。当然,我的主要观点是站得住脚的。该消息不是一个严重的问题,可以放心地忽略。
      • 感谢您的解释。我知道我可以忽略警告,但我希望不要担心。根据您的建议,我可以找到替换 lambda 表达式的方法。 sv.post(() -> sv.fullScroll(ScrollView.FOCUS_DOWN)); 似乎 sourceCompatibility 和 targetCompatibility 都是必需的。但是当我在 Android Studio 中按下运行按钮时,我得到 com.sun.tools.javac.code.Symbol$CompletionFailure: class file for java.lang.invoke.MethodType not found 错误。我应该退出使用 lambda 吗?
      • @xanadu62 我建议您谷歌该错误消息以找出解决方法。
      • 谷歌搜索是一个更好的选择。除此之外,如果您的问题中指定的问题得到解决,那么您应该接受一个答案:) 快乐编码。
      【解决方案4】:

      首先要知道compile time errorsrun-time errors的区别。

      进一步阅读运行时与编译时错误:
      Runtime vs Compile time
      Warnings and Errors

      您得到错误背后的原因是它在 Java

      这个问题的解决方法是你应该把你的项目的Java版本改为1.8

      这是执行此操作的过程:
      Using JDK 7 Or Higher With Android Studio And Eclipse On Mac OSX

      我希望这会有所帮助。

      【讨论】:

      • 更重要的是,OP 需要了解 warnings 和编译器错误之间的区别。
      • 感谢您的建议,我已经更新了我的答案。
      • 另外,您提供的链接似乎提供了设置 AS 使用的 JDK 安装的说明。它不涉及设置控制源代码中支持哪个 Java 版本及其附带功能的选项。
      • 好的。感谢您告诉我有关错误和警告、运行时和编译时的信息。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多