gpt4 book ai didi

java - 为什么 Stream.sorted 在 Java 8 中不是类型安全的?

转载 作者:IT老高 更新时间:2023-10-28 20:48:03 31 4
gpt4 key购买 nike

这是来自 Oracle JDK 8 实现的 Stream 接口(interface):

public interface Stream<T> extends BaseStream<T, Stream<T>> {
Stream<T> sorted();
}

并且在运行时很容易将其炸毁,并且在编译时不会生成警告。这是一个例子:

class Foo {
public static void main(String[] args) {
Arrays.asList(new Foo(), new Foo()).stream().sorted().forEach(f -> {});
}
}

编译得很好,但会在运行时抛出异常:

Exception in thread "main" java.lang.ClassCastException: Foo cannot be cast to java.lang.Comparable

sorted 方法没有定义在编译器可以实际捕捉到此类问题的地方,这可能是什么原因?也许我错了,但不是这么简单吗:

interface Stream<T> {
<C extends Comparable<T>> void sorted(C c);
}

?

显然,实现这一点的人(在编程和工程方面比我早几年)肯定有一个我看不到的很好的理由,但那是什么原因呢?

最佳答案

本质上,您是在询问是否有办法告诉编译器,“嘿,这种方法要求类型参数匹配比在类级别定义的更具体的界限”。这在 Java 中是不可能的。这样的功能可能很有用,但我也预计会令人困惑和/或复杂。

也没有办法制作Stream.sorted()当前实现泛型的方式是类型安全的;如果你想避免要求 Comparator .例如,您提出的建议如下:

public interface Stream<T> {

<C extends Comparable<? super T>> Stream<T> sorted(Class<C> clazz);

} // other Stream methods omitted for brevity

很遗憾,无法保证 Class<C>可从 Class<T> 分配.考虑以下层次结构:

public class Foo implements Comparable<Foo> { /* implementation */ }

public class Bar extends Foo {}

public class Qux extends Foo {}

您现在可以拥有 StreamBar元素,但尝试将其排序为 StreamQux元素。

Stream<Bar> stream = barCollection.stream().sorted(Qux.class);

由于BarQux匹配 Comparable<? super Foo>没有编译时错误,因此没有添加类型安全。此外,需要 Class 的含义论点是它将用于类型转换。在运行时,如上所示,这仍然会导致 ClassCastException s。如果 Class 用于强制转换,那么这个参数就完全没用了;我什至认为它有害。

下一个合乎逻辑的步骤是尝试要求 C延长 T以及 Comparable<? super T> .例如:

<C extends T & Comparable<? super T>> Stream<T> sorted(Class<C> clazz);

这在 Java 中也是不可能的,并且会导致编译错误:“类型参数不能跟随其他边界”。即使这是可能的,我也不认为它会解决所有问题(如果有的话)。


一些相关说明。

关于Stream.sorted(Comparator) : 不是 Stream使这个方法类型安全的,它是 Comparator . Comparator确保可以比较元素。为了说明,对 Stream 进行排序的类型安全方法按元素的自然顺序是:

Stream<String> stream = stringCollection.stream().sorted(Comparator.naturalOrder());

这是类型安全的,因为 naturalOrder()需要其类型参数扩展 Comparable .如果 Stream 的泛型类型未延长 Comparable那么边界将不匹配,从而导致编译错误。但同样,它是 Comparator要求元素为 Comparable *Stream根本不在乎。

所以问题就变成了,为什么开发人员要包含一个无参数 sorted Stream的方法|首先?这似乎是出于历史原因,并在 an answer to another question 中进行了解释。通过霍尔格。


* Comparator要求元素为 Comparable在这种情况下。一般情况下,Comparator显然能够处理它定义的任何类型。

关于java - 为什么 Stream.sorted 在 Java 8 中不是类型安全的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53219523/

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