【问题标题】:What is lub(null, Double)?什么是 lub(null, Double)?
【发布时间】:2017-09-16 06:58:15
【问题描述】:

JLS 版本 8 中的Table 15.25-B 表示条件表达式的类型

true ? null : 0.0

lub(null,Double),其中lub 似乎是section 4.10.4 的一些疯狂难以理解的东西。

这似乎与Double 类型不同,或者他们可能只是写Double,就像他们在表格中的其他地方所做的那样。不过,目前尚不清楚可能有什么不同。我试图从第 4.10.4 节中解决它,但是当我到达关于的部分时

设 lub(U1 ... Uk) 为:

最佳(W1) & ... & 最佳(Wr)

他们好像在说这种类型是 null 和 Double 类型的 交集类型,这没有任何意义。

lub(null, Double) 是什么?如果它的类型被定义为Double,具有这种类型的条件表达式的行为有何不同?

【问题讨论】:

  • 我认为它和Double 一样,就像表中的所有bnp(X, Y) 也没有被评估。
  • @kennytm:很多bnps 实际上不能折叠,因为它们表示special handling when one operand is a constant expression of type int。这让我不敢假设lubs 可以折叠。
  • 这种情况在表中表示为byte | bnp(int,byte),而不仅仅是bnp(int, byte)
  • 是的,它只是说bnp(x, y) 而不是x | bnp(y, z) 的那些似乎可以简化为普通类型,所以也许lub(null, Double) 确实简化了。
  • 当我收到 null & Double 的 lub 时,我想我知道哪里出了问题。如果我目前的理解是正确的,4.10.4 中的lub 定义确实将lub(null, Double) 解析为Double

标签: java types language-lawyer


【解决方案1】:

只是Double

非正式地,lub(null, Double) 是(一个不错的近似)最具体的类型,它包含null 类型和Double 类型的所有值,最具体的这种类型是Double

形式上,我们可以通过JLS section 4.10.4lub的定义,发现lub(null, Double)Double

一组引用类型的最小上界或“lub”是 比任何其他共享超类型更具体的共享超类型 (也就是说,没有其他共享超类型是最小上层的子类型 边界)。这种类型,lub(U1, ..., Uk),确定如下。

如果 k = 1,那么 lub 就是类型本身:lub(U) = U。

否则:

对于每个 Ui (1 ≤ i ≤ k):

令 ST(Ui) 为 Ui 的超类型集。

ST(null) is the set of all reference types,ST(Double) 是 {Object, Number, Double}。

令 EST(Ui),即 Ui 的已擦除超类型集为:

EST(Ui) = { |W| | W in ST(Ui) } 其中 |W|是W的擦除。

EST(null) 是所有引用类型的擦除集合,EST(Double) 是 {Object, Number, Double}。

令 U1 ... Uk 的已擦除候选集 EC 为所有集 EST(Ui) (1 ≤ i ≤ k) 的交集。

EC是EST(null)和EST(Double)的交集,所以EC是{Object, Number, Double}。

令 U1 ... Uk 的最小擦除候选集 MEC 为:

MEC = { V | V 在 EC 中,并且对于所有 W ≠ V 在 EC 中,情况并非如此 W <: v>

MEC 是 EC 中没有适当子类型的所有类型的集合。 Double 是 Number 和 Object 的正确子类型,因此 MEC = {Double}。 (W &lt;: V 表示 W 类型是 V 类型的子类型。类型被视为其自身的子类型,因此它们指定 W ≠ V 以仅计算正确的子类型。)

对于泛型类型的 MEC 的任何元素 G:

[大量文字]

MEC 不包含泛型类型,因此我们可以跳过。

设 lub(U1 ... Uk) 为:

最佳(W1) & ... & 最佳(Wr)

其中 Wi (1 ≤ i ≤ r) 是 MEC 的元素,最小擦除 U1 ... Uk的候选集;

如果这些元素中的任何一个是通用的,我们使用候选 参数化(以便恢复类型参数):

如果 X 是通用的,则最佳(X)= 候选(X); X 否则。

Candidate 在我们跳过的部分中定义;我们仍然可以跳过它,因为它只对泛型类型很重要。

lub(null, Double) 是Best(Double),Best(Double) 是Double,所以lub(null, Double) 是Double。

【讨论】:

  • 太棒了!我没有动力去制定定义!
【解决方案2】:

我相信lub(null, Double) === Double。不知道为什么使用lub(null, Double)。也许是为了将来允许 null 类型 的语义发生变化?

这是我的推理。根据定义,LUB = lub(T_1, ..., T_n),类型 T_1、...、T_n 的最小上界,是所有 T_1、...、T_n 的超类型,因此 LUB 没有适当的子类型,这也是所有 T_1,...,T_n 的超类型(即,它是最具体的类型,同时也是T_1,...,T_n 的超类型)。

根据定义,null 表达式的类型是 null 类型。同样根据定义,除了 null 类型 之外的所有引用类型都是 null 类型 的直接超类型。

Doublenull 类型 的超类型。 Double 本身也是一个超类型,Double 类型。所以Double 确实满足条件是所有T_1,...,T_n 的超类型。另一方面,没有其他类型可以是Double 的正确子类型并且仍然是Double 的超类型。因此,Doublelub(null, Double)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-13
    • 1970-01-01
    • 2013-07-10
    • 1970-01-01
    • 1970-01-01
    • 2013-06-26
    • 1970-01-01
    相关资源
    最近更新 更多