我把这段代码写成一个另一个问题的解决办法
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调用。
Comparator.comparing( Person :: age )…但是age成员字段和此方法的返回类型都是int原语,而不是对象。
这让我困惑于为什么会这样做,因为我认为比较器需要对象,而不是原语。
这里有自动拳击吗?如果是的话,具体在哪里?是什么触发编译器或运行时在这段代码中执行自动装箱?
我希望得到一个狭窄而准确的答案,而不是同样的挥手。当我编写代码时,挥手就已经完成了!所以,现在,我并不是出于实用性的考虑,因为很明显,代码是直观的,而且代码可以工作。在这里,language-lawyer标记确实是合适的,因为我询问的是“编程语言的正式或权威规范的复杂之处”。
发布于 2022-03-25 05:48:33
我将留给读者的练习是,Person::age的解析过程将潜在适用的方法int age()标识为精确的方法引用表达式。从JLS 15.13.2中识别了目标方法
如果以下两种情况都为真,则方法引用表达式与函数类型一致:
这里的函数类型是Function<? super T, ? extends U>。T显然是Person,comparing的签名需要一些U extends Comparable<? super U>。
类型int在赋值上下文中与Integer兼容,然后也与Comparable<Integer> (JLS 5.2)兼容:
赋值上下文允许使用以下内容之一:…
https://stackoverflow.com/questions/71612495
复制相似问题