首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么使用原语‘in’的“比较器”在此代码中工作呢?如果是自动拳击,在什么时候会发生?

为什么使用原语‘in’的“比较器”在此代码中工作呢?如果是自动拳击,在什么时候会发生?
EN

Stack Overflow用户
提问于 2022-03-25 05:20:35
回答 1查看 81关注 0票数 1

我把这段代码写成一个另一个问题的解决办法

代码语言:javascript
复制
record Person( String name , int age ) { }
List < Person > persons =
        List.of(
                new Person( "Alice" , 52 ) ,
                new Person( "Bob" , 23 ) ,
                new Person( "Carol" , 39 )
        );

List < Person > sorted =
        persons
                .stream()
                .sorted( Comparator.comparing( Person :: age ) )
                .toList();

此代码在Java 17上成功运行。

persons.toString() = [Personname=Alice,age=52,Personname=Bob,age=23,Personname=Carol,age=39] sorted.toString() = [Personname=Bob,age=23,Personname=Carol,age=39,Personname=Alice,age=52]

经过进一步的思考,我很惊讶这个代码能工作。我将记录上的访问器方法(“getter”)的方法引用传递给Comparator.comparing调用。

代码语言:javascript
复制
Comparator.comparing( Person :: age )

…但是age成员字段和此方法的返回类型都是int原语,而不是对象。

这让我困惑于为什么会这样做,因为我认为比较器需要对象,而不是原语。

这里有自动拳击吗?如果是的话,具体在哪里?是什么触发编译器或运行时在这段代码中执行自动装箱?

我希望得到一个狭窄而准确的答案,而不是同样的挥手。当我编写代码时,挥手就已经完成了!所以,现在,我并不是出于实用性的考虑,因为很明显,代码是直观的,而且代码可以工作。在这里,language-lawyer标记确实是合适的,因为我询问的是“编程语言的正式或权威规范的复杂之处”。

EN

回答 1

Stack Overflow用户

发布于 2022-03-25 05:48:33

我将留给读者的练习是,Person::age的解析过程将潜在适用的方法int age()标识为精确的方法引用表达式。从JLS 15.13.2中识别了目标方法

如果以下两种情况都为真,则方法引用表达式与函数类型一致:

  • 函数类型标识与引用对应的单个编译时声明。
  • 以下内容之一是正确的:…
    • 函数类型的结果是R,将捕获转换(§5.1.10)应用到所选编译时声明的调用类型的返回类型(§15.12.2.6)的结果是R‘(其中R是可用于推断R’的目标类型),并且R和R‘在赋值上下文中都不无效,并且R’与R兼容。

这里的函数类型是Function<? super T, ? extends U>T显然是Personcomparing的签名需要一些U extends Comparable<? super U>

类型int在赋值上下文中与Integer兼容,然后也与Comparable<Integer> (JLS 5.2)兼容:

赋值上下文允许使用以下内容之一:…

  • 装箱转换,后面是扩大引用转换
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71612495

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档