简体   繁体   English

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

[英]Java instance type with generic version 8 vs 17

As per Java Generic and Collections by Maurice Naftalin, in below options-根据 Maurice Naftalin 的 Java Generic 和 Collections,在以下选项中 -

  1. obj instanceof List对象实例列表
  2. obj instanceof List<?> obj 实例列表<?>
  3. obj instanceof List<? obj 实例列表<? extends Object>扩展对象>

1st and 2nd is permitted but 3rd is not which works fine in java 8(version "1.8.0_321").第一和第二是允许的,但第三不是在 java 8(版本“1.8.0_321”)中工作正常。 Option 1 and 2 compile and option 3 gives compile error.选项 1 和 2 编译,选项 3 给出编译错误。 But 3rd option work fine with java 17(version "17.0.1" 2021-10-19 LTS).但是第三个选项适用于 java 17(版本“17.0.1”2021-10-19 LTS)。 Could you please help me understand why its working in java 17. sample code which I am trying -你能帮我理解为什么它在 java 17. 我正在尝试的示例代码 -

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

Prior to Java 16, the only purpose of instanceof was to check whether a referenced object is assignable to the specified type and since type erasure prevents from checking whether an object truly is assignable to a parameterized type, it made no sense to allow an expression pretending that such a test was possible.在 Java 16 之前, instanceof的唯一目的是检查引用的 object 是否可分配给指定的类型,并且由于类型擦除阻止检查 object 是否真的可分配给参数化类型,因此允许表达式伪装是没有意义的这样的测试是可能的。

The only thing which could be tested, was whether the object is an instance of List and hence, it was only allowed to write … instanceof List or … instanceof List<?> , as neither pretends to test the list's element type.唯一可以测试的是 object 是否是List的实例,因此,它只允许写… instanceof List… instanceof List<?> ,因为两者都没有假装测试列表的元素类型。

Starting with Java 16 (available as preview since 14), instanceof allows to declare a new variable of the specified type.从 Java 16(自 14 开始提供预览版)开始, instanceof允许声明指定类型的新变量。

For example:例如:

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

which is equivalent to这相当于

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
    }
}

For the declaration of a new variable, it would be impractical to be limited to raw types or wildcard types.对于新变量的声明,仅限于原始类型或通配符类型是不切实际的。 Therefore, it is now allowed to specify actual type arguments, which are relevant to the implied variable declaration and assignment.因此,现在允许指定与隐含变量声明和赋值相关的实际类型 arguments。 Since the element type still can't be checked, you are only allowed to specify types to which the compile-time source type could be cast without an unchecked cast.由于仍然无法检查元素类型,因此您只能指定编译时源类型可以在没有未经检查的强制转换的情况下强制转换为的类型。

So, the following would not be valid因此,以下内容无效

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

because you can't safely cast from Iterable<?> to List<String> .因为您不能安全地从Iterable<?>转换为List<String>

In your example, var a = List.of(2,3,4,5,23);在您的示例中, var a = List.of(2,3,4,5,23); declares a as List<Integer> , hence, a instanceof List<? extends Object> a声明为List<Integer> ,因此, a instanceof List<? extends Object> a instanceof List<? extends Object> is valid because List<Integer> is assignable to List<? extends Object> a instanceof List<? extends Object>是有效的,因为List<Integer>可以分配给List<? extends Object> List<? extends Object> (even without a cast). List<? extends Object> (即使没有演员表)。

Of course, specifying element types which are not checked is only useful if you declare a variable like in the first example.当然,指定未检查的元素类型仅在您像第一个示例中那样声明变量时才有用。 But the Java language follows the principle of not adding extra rules just because some construct is less useful than the other.但是 Java 语言遵循不添加额外规则的原则,因为某些构造比其他构造不太有用。 Therefore, you can now always specify actual type arguments to instanceof following the same rules, whether you declare a variable or not.因此,无论您是否声明变量,您现在始终可以按照相同的规则将实际类型 arguments 指定给instanceof

This feature is called Pattern Matching as it is considered a special case of a broader concept which Java is heading for.此功能称为模式匹配,因为它被认为是 Java 所追求的更广泛概念的特例。 In JDK 17, there's a similar feature for switch available as preview.在 JDK 17 中,有一个类似的switch功能可用作预览版。

See also §14.30.另见§14.30。 Patterns in the Java Language Specification. Java语言规范中的模式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM