【发布时间】:2016-12-22 23:21:13
【问题描述】:
在 Java 语言规范的 §15.12.2.5 中,他们描述了 Java 如何从 可访问 和 适用 方法列表中选择最具体的方法来调用。
有一个具体的说法我不明白,即:
(1) 对于任何表达式,类型 S 比类型 T 更具体 如果 S <: t>
真正困扰我的部分是“任何表达”。
举个例子,我将引用上一段,当给定两个方法 m1 和 m2 我们可以说 m1对于带有参数表达式 e1, ..., ek 比 m2 更具体 /sub> 如果:
m2 不是泛型的,m1 和 m2 可以通过严格或宽松来适用 调用,其中 m1 具有形式参数类型 S1、...、Sn 和 m2 有形参类型 T1, ..., Tn,类型 Si 更具体 比 Ti 为参数 ei 为所有 i (1 ≤ i ≤ n, n = k)。
所以如果类型 Si (m1) 比 Ti (m2 ) 对于所有 i,参数表达式为 ei,则 m1 比 m2
更具体 >现在考虑一下:
int a(Number a) { return 1; } // m1
int a(Double a) { return 2; } // m2
由于Double <: Number,因此对于任何表达式Double 都比Number 更具体(来自引用1)。
我们有:
m1 : S1 => 数字
m2 : T1 => 双倍
但是如果我们的参数参数表达式 e1 的类型是 Number m2 是最具体的方法,因为 Double 是最具体的 任何表达式(引用 1)。
但是,如果我们将Number 传递给a(),则结果是1,即。没有选择采用Double 的方法。但是引用1说如果Double是Number的子类型对于任何表达式Double会更具体,那么它怎么会选择a(Number)?
我在这里错过了什么?
注意:
我知道Number 不能分配给Double,编译器选择另一个是没有意义的,我只是想看看我从第一个引用中误解了什么。
【问题讨论】:
-
这让我很困惑。您已经引用了“and applicable”,然后您想知道为什么不选择具有不适用参数类型的方法,即使它具有更具体的类型并且会被使用 如果适用吗?什么?
a(Double)不使用Number,这里没什么好说的了。 -
@Tom 天哪。当基本前提是错误的时,我经历了所有试图理解这一点的麻烦。我认为它始终适用。非常感谢!
-
您可以用其他类型重新考虑这些规则,例如
Double、Integer和null(只是为了它的见鬼 :D)。也许还有一些原语。这可能很有趣。 -
恕我直言,更重要的是决定是在编译时做出的,而不是在运行时。
-
@Tom 是的,我会的,我只是误解了引用扩展并认为它是适用的,只是因为它们位于同一继承树上
标签: java language-lawyer jls