java - Java 中如何推断泛型类型?
问题描述
Function.identity()
返回一个函数,该函数Function<T, T>
始终返回其输入参数(即标识函数)。
T
但是作为一个静态方法,当它甚至不接受任何输入时,它如何知道返回哪个具体参数来代替类型参数呢?
我的思考过程图解:
Map idToPerson = people.collect( Collectors.toMap( (person -> person.getID() , Function.identity() ) );
问题:那么编译器如何确定尽管没有输入但Function.identity()
应该返回流?Function<element of 'people' stream, element of 'people' stream>
根据OpenJDK,实现类似于:
static <T> Function<T, T> identity()
{
return t -> t;
}
试图缩小我的问题:
如何Function.identity()
知道(顺便说一句,这是 lambda )中的具体数据类型是什么t
?t -> t
Function<T, T>
解决方案
Java 类型推理算法基于对推理变量的约束公式的解析。它在Java 语言规范的第 18 章中有详细描述。这有点涉及。
非正式地,对于上面的例子,推理大致如下:
我们调用了Function.<T>identity()
. 因为大多数类型参数都命名为T
,并且与 JLS 一致,所以我将使用希腊字母来表示推理变量。所以在这个初始表达式T :: α
中。我们有什么限制α
?
那么返回一个用作参数identity()
的实例。Function<α,α>
toMap
static <T,K,U> Collector<T,?,Map<K,U>> toMap(Function<? super T,? extends K> keyMapper,
Function<? super T,? extends U> valueMapper)
所以现在我们有了约束{α :> T, α <: K}
(其中:>
意味着超类型,反之亦然)。现在这需要我们在这个表达式中推断T
和K
,我们将其称为β
and γ
,所以:{α :> β, α <: γ}
。为避免陷入细节困境,让我们β
只做一遍。
toMap
然后返回一个收集器作为 的参数Stream.collect
,它为我们提供了另一个约束源:
collect(Collector<? super T,A,R> collector)
所以现在我们知道了{β :> T}
。但是这里T
也需要推理,所以就变成了推理变量,我们就有了{β :> δ}
。
这是它开始展开的地方,因为T
方法的类型参数是collect
指. 所以假设流被定义为,现在我们有并且我们可以减少如下:T
Stream<T>
Stream<Person>
{δ=Person}
{β :> δ} => {β :> Person}
(β
是Person
) 的超类型;{α :> β} => {α :> (β :> Person)} => {α :> Person)}
(α
是Person
) 的超类型;
因此,通过推理过程,我们发现类型变量 forFunction.identity
需要是Person
或 的超类型Person
。类似的过程α <: γ
会产生{α <: Person}
(如果指定了返回类型)。所以我们有两个约束:
α
需要是Person
或 的超类型Person
;α
需要是;Person
的子类型Person
显然,满足所有这些约束的唯一类型是Person
.
推荐阅读
- angular - Angular Async Pipe 未订阅 EventEmitter 的初始值
- angular - 为什么 Intro js 元素选择在 mat 卡中不起作用
- python - 我正在尝试将 Twilio 广播 SMS 功能添加到我的 Django 应用程序,但无法弄清楚如何检索所有数据库电话号码
- java - 如何测试作业类引用是否属于特定类(JNI)
- arrays - 在 Swift 中解码没有键的 JSON 数组
- python - 使用 Cron Job 运行 python 程序
- apache-spark - 为什么我在运行 spark 作业时收到 java.net.SocketException
- python - 我如何使用 python 3 从 tkinter 窗口观看我的树莓派 picamera?
- security - CVE-2020-36328 关注 Centos 7 上的枕头使用 libwebp 0.3.0-3 吗?
- pine-script - strategy.entry 上的 Pine Script 版本 4 限制参数不运行