问题描述
JLS §5.2包含一些Java 8的JLS没有的新类型转换用例,请参见列表中的项目4和项目5:
分配上下文允许使用以下之一:
- 身份转换
- 不断扩大的原始转换
- 参考范围的扩大
- 参考转换范围扩大,然后取消装箱转换
- 扩展参考转换,然后是拆箱转换,然后是扩展原语转换
- 拳击转换
- 装箱转换,然后是扩大的参考转换
- 拆箱转换
- 取消装箱转换,然后扩展原始转换
我不了解列表中的情况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的关系不大。