为什么使用原始“int”的“Comparator”在这段代码中起作用?如果自动装箱,什么时候发生?
我将此代码编写为另一个问题的解决方案:
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() = [Person[name=Alice,age=52],Person[name=Bob,age=23],Person[name=Carol,age=39]]
sorted.toString() = [人物[姓名=鲍勃,年龄=23],人物[姓名=卡罗尔,年龄=39],人物[姓名=爱丽丝,年龄=52]]
经过进一步思考,我对这段代码的工作原理感到惊讶。我将 记录 上的访问器方法(“getter”)的方法引用传递给 Comparator.comparing
调用。
Comparator.comparing( Person :: age )
…但是age
成员字段和该方法的返回类型都是int
基元,而不是对象。
I wrote this code as a solution on another Question:
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();
This code runs successfully on Java 17.
persons.toString() = [Person[name=Alice, age=52], Person[name=Bob, age=23], Person[name=Carol, age=39]]
sorted.toString() = [Person[name=Bob, age=23], Person[name=Carol, age=39], Person[name=Alice, age=52]]
Upon further thought, I am surprised this code works. I pass a method reference for the accessor method (“getter”) on the record to Comparator.comparing
call.
Comparator.comparing( Person :: age )
… but age
member field, and the return type of this method, are both int
primitive, not an object.
???? This leaves me puzzled as to why this works, because I would think the comparator requires objects, not primitives.
Is there some auto-boxing at play here? If so, exactly where? What triggers the compiler or runtime to perform auto-boxing in this code?
I am hoping for a narrow and precise answer rather than same hand-waving. The hand-waving was already done when I authored the code! So, now, I am not asking out of practicality, as clearly the code is intuitive and the code works. The language-lawyer
tag is indeed appropriate here, as I am asking about the “intricacies of formal or authoritative specifications of programming languages”.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我将留给读者一个练习,即
Person::age
的解析过程识别潜在适用的方法intage()
作为精确方法引用表达式。确定目标方法后,来自 JLS 15.13.2:这里的函数类型是
Function
。T
显然是Person
,而comparing
的签名需要一些U extends Comparable
。int
类型与赋值上下文中的Integer
兼容,随后也与Comparable
兼容( JLS 5.2):I'll leave as an exercise for the reader that the resolution process for
Person::age
identifies the potentially-applicable methodint age()
as an exact method reference expression. Having identified the target method, from JLS 15.13.2:The function type here is
Function<? super T, ? extends U>
.T
is clearlyPerson
, and the signature ofcomparing
requires someU extends Comparable<? super U>
.The type
int
is compatible withInteger
in an assignment context and then subsequently also compatible withComparable<Integer>
(JLS 5.2):