Generyki - ograniczony argument wieloznaczny kontra ograniczony parametr typu

1

Witajcie!

Poduczam się ostatnio z generyków, jako, że mam chwilę.
Odtwarzam przykłady z kompendium Herberta Schildt'a i trafiłem na pewien przykład, który sam przerobiłem.
Od razu pokazuję o co chodzi: to jest przykład z kompendium, a to jest moja przeróbka.
Moje pytanie brzmi - skoro argument wieloznaczny ? oznacza dowolny poprawny typ dla danej klasy/metody/konstruktora... to jaki jest sens jego wykorzystania w w/w przykładzie, skoro można to zrobić za pomocą <T extends ...>?

Co przemawia za użyciem argumentu wieloznacznego? Dlaczego jest on lepszy w tym momencie? A może po prostu przykład jest taki, że sytuacja tego nie wymaga, jednakże autor chciał pokazać taką możliwość?

1

Pomiędzy przykładami, które podałeś, nie ma żadnej różnicy. Nie odwołujesz się do typu T, więc jedynie niepotrzebnie go wprowadzasz. Autor przykładu chciał zapewne tego uniknąć, skoro Java daje taką możliwość. Uprościł kod.
//tak, w poprzednim poście nie zrozumiałem pytania

0

@Jaca777: Jesteś w stanie mi powiedzieć, kiedy będę potrzebował skorzystać z argumentu wieloznacznego, a kiedy z parametru typu?
Jest jakaś główna zasada?
Bo jak na razie to wiem, że argument wieloznaczny wykorzystujemy, kiedy potrzebujemy skorzystać z dowolnego poprawnego typu, ale nie precyzujemy jaki musi być.
Przykład z książki przedstawia to w ten sposób w metodzie boolean sameAvg(Stats<?> ob):

public class Stats<T extends Number> {
    T[] nums;

    public Stats(T[] nums) {
        this.nums = nums;
    }

    double average() {
        double sum = 0.0;

        for (int i = 0; i < nums.length; i++) {
            sum += nums[i].doubleValue();
        }

        return sum/nums.length;
    }

    boolean sameAvg(Stats<?> ob) {
        return average() == ob.average();
    }
}

1

Jeśli nie będziesz potrzebował możliwości odwoływania się do tego typu, to najlepiej określić go właśnie parametrem wieloznacznym. Do tego stosuje się je, gdy chce się określić przez type bound lub sprowadzić do dowolnego poprawnego typu parametr zmiennej w metodzie. Gdyby dla każdej takie trzeba by było wprowadzać nowy parametr do metody, to zrobiłby się niepotrzebny bałagan.

0

Moim zdaniem niepotrzebnie dodajesz typ na starcie, powinieneś właśnie korzystać z "?".

Tzn.

    static <T extends FourD> void showXYZT(Coords<T> c)  //...

lepiej użyć:

    static void showXYZT(Coords<? extends FourD> c)  //...

Jeśli chodzi o zasady stosowania generyków w Javie to warto zapoznać się z PECS:
http://stackoverflow.com/questions/2723397/what-is-pecs-producer-extends-consumer-super

2

Znak ? oznacza, że nie znasz typu nie będziesz go znał, ani używał. Użycie oznacza w tym przypadku:

  • zdefiniowanie zmiennej lokalnej o podanym typie
  • przekazanie zmiennej do innej metody jako parametr
  • zwrócenie wartości danego typu.

Jeżeli chcesz używać podanego typu, to należy użyć literału, konwencja mówi T. Dodatkowo jest lekka różnica w semantyce, którą wskazał @wartek01.

1 użytkowników online, w tym zalogowanych: 0, gości: 1