gpt4 book ai didi

具有通用版本 8 和 17 的 Java 实例类型

转载 作者:行者123 更新时间:2023-12-05 00:51:52 26 4
gpt4 key购买 nike

根据 Maurice Naftalin 的 Java Generic 和 Collections,在以下选项中-

  1. obj 实例列表
  2. obj 实例列表
  3. obj 实例列表

第 1 和第 2 是允许的,但第 3 不是在 java 8(版本“1.8.0_321”)中工作正常。选项 1 和 2 编译,选项 3 给出编译错误。但是第三个选项适用于 java 17(版本“17.0.1”2021-10-19 LTS)。你能帮我理解为什么它在java 17中工作吗?我正在尝试的示例代码 -

var a = List.of(2,3,4,5,23);
var b = a instanceof List<? extends Object>;
return b;

最佳答案

在 Java 16 之前,instanceof 的唯一用途是检查引用的对象是否可分配给指定的类型,并且由于类型删除会阻止检查对象是否真正可分配给参数化类型,因此允许表达式假装这样的测试是可能的是没有意义的。

唯一可以测试的是对象是否是 List 的实例。因此,它只允许写… instanceof List… instanceof List<?> ,因为两者都没有假装测试列表的元素类型。

从 Java 16 开始(自 14 起提供预览版),instanceof允许声明指定类型的新变量。

例如:

public void someMethod(Iterable<String> i) {
if(i instanceof List<String> l) {
if(l.isEmpty()) return;
// optimized List processing
} else {
// generic iterable processing
}
}

相当于

public void someMethod(Iterable<String> i) {
if(i instanceof List<String>) {
List<String> l = (List<String>)i;
if(l.isEmpty()) return;
// optimized List processing
} else {
// generic iterable processing
}
}

对于新变量的声明,仅限于原始类型或通配符类型是不切实际的。因此,现在允许指定与隐含变量声明和赋值相关的实际类型参数。由于仍然无法检查元素类型,因此您只能指定编译时源类型可以在没有 unchecked 强制转换的情况下强制转换为的类型。

因此,以下内容无效

Iterable<?> i = null;
boolean b = i instanceof List<String>;

因为你不能安全地从 Iterable<?> 施放至List<String> .

在您的示例中,var a = List.of(2,3,4,5,23);声明 a作为 List<Integer> ,因此,a instanceof List<? extends Object>有效,因为 List<Integer>可分配给 List<? extends Object> (即使没有类型转换)。

当然,指定不检查的元素类型仅在您像第一个示例中那样声明变量时才有用。但是 Java 语言遵循不添加额外规则的原则,因为某些构造不如其他构造有用。因此,您现在始终可以为 instanceof 指定实际类型参数。遵循相同的规则,无论你是否声明变量。

此功能称为 Pattern Matching因为它被认为是 Java 正在走向的更广泛概念的一个特例。在 JDK 17 中,switch 有一个类似的功能。可预览。

另见 §14.30. Patterns在 Java 语言规范中。

关于具有通用版本 8 和 17 的 Java 实例类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70969598/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com