相关疑难解决方法(0)

Java 14 记录文档中“浅不可变”的含义

我正在阅读Records的文档, 但不理解“浅不可变”一词。我们所说的浅不可变是什么意思?如果它是不可变的,为什么我们需要一个复制构造函数?为什么有两个“Hello World!”?

对于所有记录类,以下不变量必须成立:如果记录 R 的组件是 c1、c2、... cn,那么如果记录实例被复制如下:

 R copy = new R(r.c1(), r.c2(), ..., r.cn());  // copy constructor ?
Run Code Online (Sandbox Code Playgroud)

那么一定是这样的r.equals(copy)

java java-14 java-record

26
推荐指数
2
解决办法
1565
查看次数

JLS 的哪一部分指定您不能从 List< 进行转换?将 List<Superclass>> 扩展到 List<List<Subclass>>?

(这个问题的灵感来自这个问题,我错误地回答了这个问题。)

此代码无法编译:

List<? extends List<Number>> list = new ArrayList<>();
List<List<Double>> anotherList = (List<List<Double>>) list;
Run Code Online (Sandbox Code Playgroud)

请注意,IntelliJ 不会报告任何错误。当我单击“运行”时,它只会编译失败。

我理解为什么这不能在概念层面上编译。list是“扩展的List<Number>东西”的列表,而“东西”永远不会是List<Double>,因为List<Double>它不是 的子类型List<Number>,并且因为它们具有相同的擦除,所以没有类型可以实现两者。

但是,当我尝试按照语言规范中的措辞来确定此强制转换是否有效时,我发现语言规范似乎说这是一个有效的强制转换!

这是我的推理:

强制转换满足从S( List<? extends List<Number>>) 到T( List<List<Double>>)的窄引用转换的所有三个要求。

5.1.6.1 . 允许的缩小参考转换

如果以下所有条件都为真,则存在从引用类型 S 到引用类型 T 的收缩引用转换:

  • S 不是 T 的亚型

  • 如果存在作为 T 超类型的参数化类型 X 和作为 S 超类型的参数化类型 Y,使得 X 和 Y 的擦除相同,则 X 和 Y 不可证明不同(第 4.5 节) .

  • 以下情况之一适用:

    • S 和 …

java language-lawyer

11
推荐指数
1
解决办法
170
查看次数

标签 统计

java ×2

java-14 ×1

java-record ×1

language-lawyer ×1