为什么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
的相同方法中发现了一个有趣的问题:
static <T> Stream<T> empty()
我们可以看到方法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>()...
我们实际上已经使 R
和 T
等效,这可能是他们在声明中仍然使用 T
的原因empty()
而不是其他类型。
现在让我们将相同的逻辑应用到 findAny
:
public <T> Optional<T> findAny();
这将生成一条警告 - 您正在隐藏在 class 级别 (Stream<T>
) 和方法中声明的 <T>
。发生这种情况是因为 findAny
不是 静态的并且它使用已经声明的类型参数 - 你通过引入另一个与那个没有关系的 <T>
来隐藏它形成 class 级别。
在Java 8的流库中,我在java.util.stream.Stream
的相同方法中发现了一个有趣的问题:
static <T> Stream<T> empty()
我们可以看到方法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>()...
我们实际上已经使 R
和 T
等效,这可能是他们在声明中仍然使用 T
的原因empty()
而不是其他类型。
现在让我们将相同的逻辑应用到 findAny
:
public <T> Optional<T> findAny();
这将生成一条警告 - 您正在隐藏在 class 级别 (Stream<T>
) 和方法中声明的 <T>
。发生这种情况是因为 findAny
不是 静态的并且它使用已经声明的类型参数 - 你通过引入另一个与那个没有关系的 <T>
来隐藏它形成 class 级别。