当前位置: 首页 > 知识库问答 >
问题:

非静态方法不能从Java 8流中的静态上下文中引用

聂翼
2023-03-14

我使用了http://www.concretepage.com/java/jdk-8/java-8-unaryoperator-binaryoperator-example中的示例。

我发现真正令人困惑的是,当我在形成收集器时错误地将一个错误的类型放入其中一个泛型中时,Java编译器给了我一个非常误导的信息:

不能从静态上下文引用非静态方法

我的错误与现实中的静态vs实例上下文无关:

Map<String, Map<Integer, Integer>> mapOfStudents = list.stream().collect(Collectors.groupingBy(Student::getClassName,
            Collectors.toMap(Student::getName, Student::getAge)));

我的错误是在泛型返回类型。当我更正它并放:

Map<String, Map<String, Integer>> mapOfStudents

一切都恢复正常了。

有人能解释一下这样一条令人迷惑的错误信息背后的原因吗?我肯定这是一个好的,但我没有把握住它。

编辑:

~$ java -version
openjdk version "1.8.0_121"
OpenJDK Runtime Environment (build 1.8.0_121-8u121-b13-0ubuntu1.16.04.2-b13)
OpenJDK 64-Bit Server VM (build 25.121-b13, mixed mode)

共有1个答案

干永丰
2023-03-14

首先需要注意的是,消息不是由Java编译器(javac)发出的,而是由IntelliJ IDEA发出的。当实际启动构建过程时,您可以在“messages build”窗口中看到javac消息。您在编辑器窗口中看到的是由IDEA本身生成的消息,它们可能会有所不同。

由于在IntelliJ IDEA中实现了方法引用解析,错误消息具有误导性。只有当相应的SAM(单个抽象方法)参数个数等于方法参数个数加1且第一个SAM参数类型与包含类的方法兼容时,才考虑解析非静态方法引用。请参见实现(也是上面的isSecondSearchPossible方法,对varargs方法执行了一些附加的魔术)。

如果你的程序没有错误,它就能正常工作。但是,如果具有不匹配的类型,则传递到tomap中的函数的泛型参数不能替换,因此它仍然保留函数 ,其apply方法的第一个参数只是t,它与类型student不对应。因此,所谓的“二次搜索”失败了,IDEA认为该方法是从静态上下文中引用的。虽然静态和非静态上下文在这里都不适用,但非静态上下文与您的方法匹配得更好,至少根据参数的数量是这样的,因为getName()方法没有接收任何参数。另一方面,IDEA逻辑是“如果非静态上下文不适用,那么它是静态上下文”,因此错误消息。

我认为这是一个bug,或者至少是一个可用性问题。我只是根据类似的问题把它记录在这里。希望我们能修好它。

免责声明:我是IntelliJ IDEA开发人员。

更新:在IDEA 2017.2中修正。

 类似资料:
  • 问题内容: 我想一劳永逸地理解这一点。 为此,请原谅下面粘贴的大量代码,但是我不想遗漏任何细节。 我唯一更改的是加载的URL。但这不会导致错误。 我想将我的函数称为“ readPosiitons ”。简单的解决方案,使其静态。真正的解决方案,我不确定。 请帮助我更好地了解如何以正确的方式解决此错误。 谢谢!! 问题答案: 真正的解决方案?不要在方法中放太多东西。那是给菜鸟的。 Java是一种面向对

  • 问题内容: 不需要任何代码,只需要某种指导。希望保持我的学术诚信;) 我不断收到那个烦人的错误。我需要为每个Room实例调用toString方法。有什么建议?如果可能的话,我希望在2小时内给出答案。 问题答案: 您不应尝试调用Room类,而应调用Room 对象 。在该方法中,请使用for循环遍历房间数组,并打印通过调用数组中保存的每个Room对象返回的String,因为这是您的方法应做的事情。 例

  • 所以我尝试绑定我的Numpad键,以便在计算器应用程序中使用它们,但当我尝试从主窗口以字符串形式发送keyEvent时。java到我的MainWindowController公共void方法它给了我一个错误“不能从静态上下文引用非静态方法”,即使我的类都不是静态的?以下是主窗口代码: } 这里是MainWindowController文件(看keyPress方法)

  • 我想更改FrameLayout的背景。这是我现在使用的代码: 但出现以下错误: 无法从静态上下文引用非静态方法“setBackground(android.graphics.drawable.drawable)”。 怎么了?

  • 我从这行中得到了“无法从静态上下文引用非静态方法”错误:

  • mainactivity.java: xmlReader.java: (如果需要,我也可以为station.java和dbhandler.java添加代码) 我怎样才能绕过这个编程悖论呢?我通常能为这里的任何问题找到答案,但这是我第一次找不到答案。如果你知道我错过的解决方案的链接,请在下面发布。多谢。