热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

无法从java8流中的静态上下文引用非静态方法

如何解决《无法从java8流中的静态上下文引用非静态方法》经验,为你挑选了1个好方法。

我正在讨论来自http://www.concretepage.com/java/jdk-8/java-8-unaryoperator-binaryoperator-example的例子.

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

无法从静态上下文引用非静态方法

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

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

我的错误在于泛型返回类型.当我纠正它并把:

Map> 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)

Tagir Valeev.. 36

首先应该注意,消息不是由java编译器(javac)发出的,而是由IntelliJ IDEA发出的.实际启动构建过程时,可以在"Messages Build"窗口中看到javac消息.您在编辑器窗口中看到的是IDEA自己生成的消息,它们可能有所不同.

由于在IntelliJ IDEA中实现了方法参考分辨率,错误消息具有误导性.它认为只有当相应的SAM(单个抽象方法)参数的数量等于方法参数的数量加上一个并且第一个SAM参数类型与包含类的方法兼容时,才能解析非静态方法引用.查看实现(也是isSecondSearchPossible上面的方法,为varargs方法执行了一些额外的魔术).

如果您的程序没有错误,它可以正常工作.但是,如果您的类型不匹配,则Function传入的泛型参数toMap不能被替换,因此它仍然存在Function,并且其apply方法的第一个参数简单地T与该类型不对应Student.因此,所谓的"第二次搜索"失败,IDEA认为该方法是从静态上下文引用的.虽然静态和非静态上下文在这里都不适用,但非静态上下文更适合您的方法,至少根据参数的数量,因为getName()方法不接受任何参数.另一方面,IDEA逻辑是"如果非静态上下文不适用,则它是静态上下文",因此是错误消息.

我认为这是一个错误,或者至少是一个可用性问题.我刚刚根据类似的问题在这里记录了它.希望我们能解决它.

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

更新:在IDEA 2017.2中修复.



1> Tagir Valeev..:

首先应该注意,消息不是由java编译器(javac)发出的,而是由IntelliJ IDEA发出的.实际启动构建过程时,可以在"Messages Build"窗口中看到javac消息.您在编辑器窗口中看到的是IDEA自己生成的消息,它们可能有所不同.

由于在IntelliJ IDEA中实现了方法参考分辨率,错误消息具有误导性.它认为只有当相应的SAM(单个抽象方法)参数的数量等于方法参数的数量加上一个并且第一个SAM参数类型与包含类的方法兼容时,才能解析非静态方法引用.查看实现(也是isSecondSearchPossible上面的方法,为varargs方法执行了一些额外的魔术).

如果您的程序没有错误,它可以正常工作.但是,如果您的类型不匹配,则Function传入的泛型参数toMap不能被替换,因此它仍然存在Function,并且其apply方法的第一个参数简单地T与该类型不对应Student.因此,所谓的"第二次搜索"失败,IDEA认为该方法是从静态上下文引用的.虽然静态和非静态上下文在这里都不适用,但非静态上下文更适合您的方法,至少根据参数的数量,因为getName()方法不接受任何参数.另一方面,IDEA逻辑是"如果非静态上下文不适用,则它是静态上下文",因此是错误消息.

我认为这是一个错误,或者至少是一个可用性问题.我刚刚根据类似的问题在这里记录了它.希望我们能解决它.

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

更新:在IDEA 2017.2中修复.


@EJP,它同意程序不正确,但错误信息不同.Java语言规范指定了什么是正确的程序,但它没有准确指出错误消息应该如何查找不正确的程序.请注意,Eclipse编译器中的错误消息也是不同的,在这种情况下实际上甚至比javac消息更好,因为您可以更容易地发现实际错误.你会认为这是Eclipse编译器中的错误吗?:-)
对我来说,“非静态和静态引用”与“通用类型不匹配”的问题相去甚远。
推荐阅读
author-avatar
lee
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有