【问题标题】:How to find stream type in java-8 [duplicate]如何在java-8中查找流类型[重复]
【发布时间】:2021-12-13 18:03:30
【问题描述】:

我有以Stream 对象作为参数的方法,在该方法中我必须根据Stream 类型执行一些操作。但是instanceof 不起作用并给我编译错误

public <T>boolean objectIsNullOREmpty(Stream<T> str) {
    if(str instanceof Stream<String>) {
        //do some actions
    }

    if(Str instanceof Stream<SomeClass>) {
        //do some actions
    }
}

编译错误

无法对参数化类型 Stream 执行 instanceof 检查。请改用 Stream 表单,因为更多的泛型类型信息将在运行时被删除

【问题讨论】:

    标签: java java-8


    【解决方案1】:

    这不是流的问题。该错误反映了泛型类型在 Java 中的实现方式。

    Java 泛型类型是不可具体化的

    在 Java 中,泛型类型在运行时可用的类型信息少于在编译时可用的类型信息。这是因为泛型是由 erasure 在 Java 中实现的。大多数泛型类型信息仅在编译时存在,并在运行时被删除。

    因此,不可能为任何不可具体化的类型获取Class 对象。类型信息在运行时不可用。

    不仅不能为Stream&lt;String&gt; 获取Class 对象,而且不能为TList&lt;T&gt;List&lt;String&gt; 中的任何一个获取Class 对象。这些都是不可具体化的类型。

    instanceof 运算符仅适用于可以从中获取Class 对象的类型。这也是一件好事,因为List&lt;T&gt;List&lt;String&gt;List&lt;Integer&gt; 在运行时都共享同一个 Class 对象。如果将以下 sn-p 评估为 true,则会令人困惑且容易出错:

    List<String> strings = new ArrayList<>();
    boolean b = strings instanceof List<Integer>;
    System.out.println(b);
    

    相反,Java 编译器不允许在不可具体化的类型上使用 instanceof 运算符。

    【讨论】:

    • 你忘了说我们可以将String 对象放入List&lt;Integer&gt; :-)
    • 我用来解释的一个例子是以下断言成立:assert new ArrayList&lt;Boolean&gt;().getClass().equals(new ArrayList&lt;String&gt;().getClass())
    【解决方案2】:

    要添加到@scottb 的答案,如果您真的需要这种结构,那么您将需要单独的方法。由于擦除,您不能重载方法,因此您必须命名每个方法,以便方法签名是唯一的:

    public boolean stringIsNullOREmpty(Stream<String> str) {
        //do some actions
    }    
    
    public boolean someClassIsNullOREmpty(Stream<SomeClass> str) {
        //do some actions
    }
    

    【讨论】:

      猜你喜欢
      • 2015-02-24
      • 2015-10-21
      • 1970-01-01
      • 1970-01-01
      • 2018-06-25
      • 1970-01-01
      • 2015-05-07
      • 2022-07-13
      相关资源
      最近更新 更多