文章出處

泛型和通配符

使用泛型和通配符都可以讓一個方法所表示的算法邏輯適應多種類型。
Java中具備繼承關系的類A、B(A extends B)它們的集合List<A>List<B>之間是沒有繼承關系的,
可以使用泛型或通配符來讓一個方法支持同時接受List<A>List<B>

代碼場景

這里分別定義類Animal、Dog和Cat,很顯然,Dog和Cat是Animal的子類。
它們的簡單定義如下:

abstract class Animal {
  public abstract boolean afraidOf(Animal other);
}

class Cat extends Animal {

  @Override
  public boolean afraidOf(Animal other) {
      if (other instanceof Dog) {
        return true;
      }
      return false;
  }
}

class Dog extends Animal {

  @Override
  public boolean afraidOf(Animal other) {
      if (other instanceof Cat) {
        return false;
      }
      return true;
  }
}

上面Animal類定義了boolean afraidOf(Animal other)方法,表示一個動物是否害怕另一個動物。

可以看到Cat和Dog有著不同的表現。

假設有下面需求:
從一個List<Animal>中找到某個Animal對象害怕的所有其它動物。
對應有以下的API方法:

public List<Animal> findScaredAnimals(List<Animal> animals, Animal who) {
  //...
}

如果這時有List<Dog>或者List<Cat>這種,也應該是支持的。
可以通過通配符或者泛型方法實現。

通配符實現

使用List<? extends Animal>這樣的形參,就可以接收集合項為Animal子類的任意List。

public List<Animal> findScaredAnimals(List<? extends Animal> animals, Animal who) {
  //...
}

這時就可以這樣調用了:

List<Dog> dogs;
....
findScaredAnimals(dogs, animal);
...

其他Animal子類的List都是可以的。

泛型方法實現

拋開實際意義,假設需要findScaredAnimals()中,返回值和參數對應的具體Animal子類型是一致的,那么就需要用到泛型了:

public <T extends Animal> List<T> findScaredAnimals(List<T> animals, T who) {
  //...
}

可以看到,泛型類型參數T同時約束了多個地方。
泛型參數也可以是多個的,而且之間存在關系。

小結

以上通過一個不太實際的案例說明了使用泛型和通配符來解決List泛型集合之間的“匹配”問題。這也是它們的主要用途之一。

(本文使用Atom編寫)


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()