Java SE 11-Java语言规范中类型转换的新情况

问题描述

Java SE 11的

JLS §5.2包含一些Java 8的JLS没有的新类型转换用例,请参见列表中的项目4和项目5:

分配上下文允许使用以下之一:

  1. 身份转换
  2. 不断扩大的原始转换
  3. 参考范围的扩大
  4. 参考转换范围扩大,然后取消装箱转换
  5. 扩展参考转换,然后是拆箱转换,然后是扩展原语转换
  6. 拳击转换
  7. 装箱转换,然后是扩大的参考转换
  8. 拆箱转换
  9. 取消装箱转换,然后扩展原始转换

我不了解列表中的情况4 情况5 。谁能给我一些例子的解释?如有可能,还请说明其实际用法。


更新

与@Naman commented一样,这是更改JLS-JDK-8166326 : 5.2: Allow widening before unboxing的提案,该提案自Java-9开始生效。在报告中,它提到:

此行为对于与捕获的互操作性特别重要各种现有程序希望能够将List<? extends Integer>的元素视为整数。

List<? extends Integer> li = null;
int i = li.get(0);

这可能意味着JLS更改确实具有实际必要性。但是我还是不明白为什么很重要。 与捕获的互操作性是什么意思,为什么它很重要?这些各种现有程序是什么样的?它们是Java代码吗(我知道其他一些语言也可以在JVM上运行,并且可能与Java代码交互)?

解决方法

TL; DR

………拳击的问题是[即席]和昂贵;为解决这两个问题,我们开展了广泛的工作” — — Brian Goetz,State of Valhalla,March 2020

这使我怀疑对您所引用规范的那些更改正在为计划的“ 代码(如类),像 L-World 在以上链接中进行了讨论。


...有人可以举例说明吗?...

2016错误报告中链接到注释(plus the 2013 one that one links to)的示例提供了列表中 #4 的最佳示例。基于这些,这是您列表中 #5 的示例...

< I extends Integer > void soAns0( I intRef ) {

   int intPrim;

   long longPrim = /* (3) a widening primitive conversion */
   intPrim =       /* (2) an unboxing conversion */
   intRef;         /* (1) a widening reference */
}

...如果可能,还请说明其实际用法...

natural numbers通常被称为“ 整数”。 Java Language Tutorial显示了一种将自然数限制为 Integer ...

类型的实际用法
public class NaturalNumber<T extends Integer> {

    private T n;

    public NaturalNumber(T n)  { this.n = n; }

    public boolean isEven() {
        return n.intValue() % 2 == 0;
    }

    // …
}

RowFilter<M,​I>的API文档中也有此示例……

…
  public boolean include(Entry<? extends PersonModel,? extends Integer> entry) {
    …
    Person person = personModel.getPerson(entry.getIdentifier());
    …
  }
…

另一个可能适合使用 T extends Integer 的用例是,如果您想显式地禁止使用任何其他类型的 Number AND 明确禁止将 Integers 添加到该参数化类型中- 通过利用Get/Put Principle

假设您有一些代码,给定数量,它将创建该数量的对象。 如果您想通过用 {Long.MAX_VALUE 次DOS尝试轰炸坏系统来阻止恶意行为者淹没您的系统,则限制 <T extends Short> 可能是一种方法限制在任何一个方法调用中将要创建的对象的数量。

...这些各种现有程序是什么样的?他们是Java代码吗?…

在github上搜索 T extends Integer 会出现eighty-thousand some hits

与捕获的互操作性是什么意思?…

我将捕获转换的明确解释推迟到the JLS itself

…为什么重要?…

捕获转换很重要,因为它与类型推断有关。

the JLS' section on type inference中的符号 ‹Integer <: α› 或多或少是表达 Integer extends Integer 的一种正式方式( { {1}}的有效意思是)…

...

T extends Integer中,我们有约束公式Arrays.asList(1,2.0)‹1 → α›。通过归约,这些将成为约束公式‹2.0 → > α›‹int → α›,然后依次是‹double → α›‹Integer <: α›

...

鉴于此,JDK本身的JDK uses <T extends Integer> a lot for Generics/Type Inference related tests也就不足为奇了。

这里是my absolute favorite use of <T extends Integer> in the wild

尽管如此,我敢打赌,与装箱/加宽相关的规格更改与Valhalla的关系不大。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...