为什么Java8中java.util.stream.Stream的empty()方法(没有任何参数)包含类型参数?

Why does the empty() method (without any parameter) of java.util.stream.Stream in Java 8 contains a type parameter?

在Java 8的流库中,我在java.util.stream.Stream的相同方法中发现了一个有趣的问题:

我们可以看到方法signature中没有参数。根据我的理解,在这种情况下,不应有 type parameter - <T> - 在 optional specifier -[=15= 之后].例如,在方法 Optional<T> findAny() 中,没有按预期给出 类型参数

那么谁能解释为什么 static <T> Stream<T> empty() 包含类型参数

让我们先声明我们自己的类型,以便更好地理解原因:

static interface Stream<T> {

    public static Stream<T> empty() { // will not compile here
        return new Stream<T>() {
        };
    }

}

因为这段代码是正确的,它不会编译,说 can not make a static reference to the non-static type T,IMO 完全有意义。发生这种情况是因为静态上下文完全独立于类型参数(这应该回答你的第一个问题)。

要解决此问题,我们需要将类型参数添加到方法中:

public static <T> Stream<T> empty() { // notice the extra <T>
   return new Stream<T>() {
   };
}

这会编译得很好,但是有一个隐藏的问题 - class T 和方法 T 完全独立并且之间没有任何关系他们

这本可以这样写,效果完全相同(并且更清晰的 IMO):

public static <R> Stream<R> empty() {
    return new Stream<R>() {
    };
}

因为你有这个:return new Stream<R>()... 我们实际上已经使 RT 等效,这可能是他们在声明中仍然使用 T 的原因empty() 而不是其他类型。

现在让我们将相同的逻辑应用到 findAny:

public <T> Optional<T> findAny();

这将生成一条警告 - 您正在隐藏在 class 级别 (Stream<T>) 和方法中声明的 <T>。发生这种情况是因为 findAny 不是 静态的并且它使用已经声明的类型参数 - 你通过引入另一个与那个没有关系的 <T> 来隐藏它形成 class 级别。