Java SE 11 - Java 语言规范中类型转换的新案例

Fra*_* Mi 14 java autoboxing type-conversion jls java-11

Java SE 11 的JLS §5.2包含一些 Java 8 的 JLS 没有的新类型转换案例,请参阅列表中的第 4 项和第 5 项:

赋值上下文允许使用以下之一:

  1. 身份转换
  2. 扩大原始转换
  3. 扩大参考转换
  4. 一个扩大的参考转换,然后是一个拆箱转换
  5. 扩展引用转换,然后是拆箱转换,然后是扩展基元转换
  6. 拳击转换
  7. 一个装箱转换,然后是一个扩大的参考转换
  8. 拆箱转换
  9. 一个拆箱转换,然后是一个扩大的原始转换

我不明白列表中的案例 4案例 5。谁能用例子给我一些解释?如果可能,还请说明其实际用途。


更新:

正如@Naman 所评论的,这里是更改 JLS 的提议 - JDK-8166326:5.2:允许在拆箱前加宽,这是自 Java-9 以来生效的。在报告中,它提到:

这种行为对于与 capture 的互操作性尤其重要各种现有程序都希望能够将 a 的元素List<? extends Integer>视为整数。

List<? extends Integer> li = null;
int i = li.get(0);
Run Code Online (Sandbox Code Playgroud)

这可能暗示着这次 JLS 的改变确实有实际的必要性。但我还是不明白为什么 <? extends Integer> 很重要。什么是与捕获的互操作性意味着,它为什么如此重要?这些现有的各种程序是什么样的?它们是 Java 代码吗(我知道其他一些语言也适用于 JVM,并且可能与 Java 代码有交互)?

ded*_*per 1

长话短说

\n
\n

\xe2\x80\x9e \xe2\x80\xa6 装箱的问题是它是[临时的]并且昂贵;为了解决这两个问题,我们已经在幕后进行了大量工作\xe2\x80\x9c \xe2\x80\x94 Brian Goetz,瓦尔哈拉州,2020 年 3 月

\n
\n

这让我怀疑您所引用的规范的这些更改正在为计划的 \xe2\x80\x9e 代码准备语言,就像一个类,其工作原理类似于上面讨论的L-World的int \xe2\x80\x9c 功能关联。

\n
\n
\n

\xe2\x80\x9e \xe2\x80\xa6有人能给我一些例子解释吗?\xe2\x80\xa6 \xe2\x80\x9c

\n
\n

评论中链接到的 2016 年错误报告中的示例(加上链接到的 2013 年错误报告)给出了列表中#4的最佳示例。基于这些,这是列表中#5的示例\xe2\x80\xa6

\n
< I extends Integer > void soAns0( I intRef ) {\n\n   int intPrim;\n\n   long longPrim = /* (3) a widening primitive conversion */\n   intPrim =       /* (2) an unboxing conversion */\n   intRef;         /* (1) a widening reference */\n}\n
Run Code Online (Sandbox Code Playgroud)\n
\n

\xe2\x80\x9e \xe2\x80\xa6如果可以的话还请解释一下它的实际用法\xe2\x80\xa6 \xe2\x80\x9c

\n
\n

自然通常称为 \xe2\x80\x9e整数\xe2\x80\x9c。Java语言教程展示了一种将自然数限制为Integer\xe2\x80\xa6类型的实际用法

\n
public class NaturalNumber<T extends Integer> {\n\n    private T n;\n\n    public NaturalNumber(T n)  { this.n = n; }\n\n    public boolean isEven() {\n        return n.intValue() % 2 == 0;\n    }\n\n    // \xe2\x80\xa6\n}\n
Run Code Online (Sandbox Code Playgroud)\n

RowFilter<M,\xe2\x80\x8bI> \xe2\x80\xa6的 API 文档中还有此示例

\n
\xe2\x80\xa6\n  public boolean include(Entry<? extends PersonModel, ? extends Integer> entry) {\n    \xe2\x80\xa6\n    Person person = personModel.getPerson(entry.getIdentifier());\n    \xe2\x80\xa6\n  }\n\xe2\x80\xa6\n
Run Code Online (Sandbox Code Playgroud)\n

另一个可能合适的用例T extends Integer是,如果您想显式禁止您的类使用任何其他类型进行参数化,并且通过利用Get/Put 原则显式 禁止添加到该参数化类型 \xe2\x80\x94 中。Number Integers

\n

假设您有一些代码,给定某个数量,将创建该数量的对象。\n如果您想禁止不良行为者通过多次Long.MAX_VALUEDOS 尝试轰炸系统来压垮您的系统,限制<T extends Short>可能是限制对象数量的一种方法它将在任何一个方法调用中创建。

\n
\n

\xe2\x80\x9e \xe2\x80\xa6 这些现有的程序是什么样子的?它们是java代码吗?\xe2\x80\xa6 \xe2\x80\x9c

\n
\n

在 github 上搜索发现T extends Integer八万个点击

\n
\n

\xe2\x80\x9e \xe2\x80\xa6与捕获的互操作性意味着什么?\xe2\x80\xa6 \xe2\x80\x9c

\n
\n

我将捕获转换的最终解释推迟到JLS 本身

\n
\n

\xe2\x80\x9e \xe2\x80\xa6 为什么它很重要?\xe2\x80\xa6 \xe2\x80\x9c

\n
\n

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

\n

JLS\' 部分\xe2\x80\xb9Integer <: \xce\xb1\xe2\x80\xba中关于类型推断的符号或多或少是表达(有效含义)\xe2\x80\xa6的正式方式Integer extends IntegerT extends Integer

\n
\n

\xe2\x80\xa6

\n

Arrays.asList(1, 2.0),我们有约束公式\xe2\x80\xb91 \xe2\x86\x92 \xce\xb1\xe2\x80\xba\xe2\x80\xb92.0 \xe2\x86\x92 > \xce\xb1\xe2\x80\xba。通过约简,这些将成为约束公式\xe2\x80\xb9int \xe2\x86\x92 \xce\xb1\xe2\x80\xba和\n \xe2\x80\xb9double \xe2\x86\x92 \xce\xb1\xe2\x80\xba,然后\xe2\x80\xb9Integer <: \xce\xb1\xe2\x80\xba\xe2\x80\xb9Double <: \xce\xb1\xe2\x80\xba

\n

\xe2\x80\xa6

\n
\n

鉴于此,JDK大量使用<T extends Integer>JDK 本身的泛型/类型推断相关测试就不足为奇了。

\n

这是我最喜欢的野外使用<T extends Integer>

\n

但大多数情况下,我敢打赌那些与拆箱/扩大相关的规范更改与瓦尔哈拉有很大关系。

\n