Vícenásobná vazba generics

Uvažujme následující metodu (bez použití generics), která vyhledává maximální prvek nějaké kolekce. Navíc platí, že prvky kolekce musí implementovat rozhraní Comparable, což, jak lze snadno nahlédnout, není syntaxí vůbec podchyceno a tudíž zavolání této metody může vyvolat výjimku ClassCastException .


      
      public static Object max(Collection c);
      
    

Nyní se pokusíme vymyslet, jak zapsat tuto metodu za použití generics. Chceme, aby prvky kolekce implementovali rozhraní Comparable. Podíváme-li se na toto rozhraní, zjistíme, že je též parametrizované generics. Potřebujeme tedy takovou instanci, která je schopná porovnat libovolné třídy v hierarchii nad třídou, která bude prvkem vstupní kolekce. První pokus, jak zapsat požadované.


      
      public static <T extends Comparable<? super T>> T max(Collection<T> c);
      
    

Tento zápis je relativně OK. Metoda správně vrátí proměnnou stejného typu, jaký je prvkem v kolekci, dokonce i použití Comparable je správné. Nicméně, pokud bychom se zajímali o signaturu metody po „výmazu“ generics, dostaneme následující.


      
      public static Comparable max(Collection c);
      
    

To neodpovídá signatuře metody výše. Využijeme tedy vícenásobné vazby.

[1]

      
      public static <T extends Object & Comparable<? super T>> T max (Collection<T> c);
      
    

Nyní, po „výmazu“ má již metoda správnou signaturu, protože v úvahu se bere první zmíněná třída. Obecně lze použít více vazeb pro generics, například chceme-li, aby obecný prvek byl implementací více rozhraní.



[1] V materiálu, ze kterého čerpám, je navíc Collection<? extends T> Domnívám se ovšem, že metoda zmíněná v tomto článku má stejnou funkcionalitu. Pokud se někomu podaří nalézt protipříklad, budu rád.