Java 中的協變和逆變是指當一個泛型類的類型參數發生變化時,其子類與父類之間的方法返回值類型的變化情況。
class Animal {} class Dog extends Animal {} class Cage{ T animal; public T getAnimal() { return animal; } public void putAnimal(T animal) { this.animal = animal; } } Cage animalCage = new Cage (); Cage dogCage = new Cage (); animalCage = dogCage; // 編譯錯誤,無法將類型為Cage 的對象賦值給類型為Cage 的變量
在上述例子中,盡管 Dog 是 Animal 的子類,但是由于泛型的不變性,Cage<Dog> 類型的對象不能直接賦值給 Cage<Animal> 類型的變量。這種情況下就需要使用協變和逆變。
協變(Covariant)是指當類型參數是子類型時,方法的返回值類型隨之變化,即派生類的類型參數可以立刻和父類的類型參數建立子父類關系。使用協變,可以將 Cage<Dog> 類型的對象賦值給 Cage<Animal> 類型的變量。
class Cage<+T>{ T getAnimal(); } CageanimalCage = new Cage ();
在使用協變時,類型參數 T 的前面加上了 + 號,表示類型參數 T 是一個協變類型。
逆變(Contravariant)是指當類型參數是父類型時,方法的參數類型隨之變化,即基類的類型參數可以立刻和派生類的類型參數建立子父類關系。
class Cage-{ void putAnimal(T animal); } Cage dogCage = new Cage ();
在使用逆變時,類型參數 T 的前面加上了 - 號,表示類型參數 T 是一個逆變類型。
協變和逆變在泛型類中的使用可以方便地實現泛型對象之間的賦值和傳遞,提高了代碼的可讀性和可維護性。