我有這個方法:
public <T extends CacheResult> T get(Object key, CacheDefinition cacheDefinition) {
return load(key, cacheDefinition.name(), cacheDefinition.getTypeReference());
}
現在我的 IDE 對這一行抱怨(正如預期的那樣,這是正確的),因為回傳型別應該是CacheResult
User user = spxCacheManager.get(username, CacheDefinition.USERS_BY_USERNAME);
我目前不明白的是,IDE(IntelliJ)并沒有抱怨這個:
List<User> usersFromCache = spxCacheManager.get(username, CacheDefinition.USERS_BY_USERNAME);
這實際上是錯誤的。我在這里缺少什么?
uj5u.com熱心網友回復:
這是有效的,因為T被推斷為交叉型別 - List<User> & CacheResult & Object。畢竟,為什么一個類不能同時實作List<User> 和實作/擴展CacheResult?這樣的型別當然是可能的!
您可以通過撰寫一個玩具程式并使用以下--debug=verboseResolution=all選項來看到這種情況:
import java.util.List;
public class Main {
public static void main(String[] args) {
List<User> u = new Main().get();
}
public <T extends CacheResult> T get() {
return null;
}
}
interface CacheResult {}
class User implements CacheResult {}
javacwithverboseResolution=all會輸出:
instantiated signature: ()INT#1
target-type: List<User>
where T is a type-variable:
T extends CacheResult declared in method <T>get()
where INT#1 is an intersection type:
INT#1 extends Object,List<User>,CacheResult
您還可以了解Java 如何進行型別推斷的程序。最終,(在“決議”的地方),你會到達一個點,你需要找到的最大下界的(“GLB”) Object,List<User>并CacheResult和該型別也正是它們的交集型別,定義在這里。
另一方面,如果您的代碼CacheResult是一個類,并且您將方法結果分配給的型別是一個不相關的類,則您的代碼將無法編譯,因為沒有一個類可以從兩個不相關的類中繼承。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/352936.html
