讓我們首先聲明自己的類型,以便更好地理解爲什麼:
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>() {
};
}
這將編譯就好了,但有一個隱藏的問題 - 類T
和方法T
是完全獨立的,他們之間沒有任何關係。
這也可以寫成這樣具有完全相同的效果(和更清潔的IMO):
public static <R> Stream<R> empty() {
return new Stream<R>() {
};
}
,因爲你有這樣的:return new Stream<R>()...
我們已經有效地做出R
和T
等同,可能是這是原因爲什麼他們仍然在empty()
的聲明中使用T
而不是其他類型。
現在讓我們套用同樣的邏輯findAny
:
public <T> Optional<T> findAny();
,這將產生一個警告 - 你是隱藏了在類級別(Stream<T>
)和一個在方法聲明的<T>
。發生這種情況的原因是findAny
不是 static,它使用已聲明的類型參數 - 通過引入另一個<T>
來隱藏該類型參數,該類型參數與類級別的類型無關。
請參閱類型推斷:https://docs.oracle.com/javase/tutorial/java/generics/genTypeInference.html –
@ holi-java我不認爲這與類型推斷有很大關係...... – Eugene
@Eugene嘿,[目標類型](https://docs.oracle.com/javase/tutorial/java/generics/genTypeInference.html#target_types)部分完全描述了它。我認爲OP開始學習泛型,所以我希望他首先看到類型推斷。 :) –