Generyki - ograniczony argument wieloznaczny kontra ograniczony parametr typu

Generyki - ograniczony argument wieloznaczny kontra ograniczony parametr typu
Burdzi0
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Futurama
  • Postów: 887
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ść?

Jaca777
  • Rejestracja: dni
  • Ostatnio: dni
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

Burdzi0
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Futurama
  • Postów: 887
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):

Kopiuj
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();
    }
}

Jaca777
  • Rejestracja: dni
  • Ostatnio: dni
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.

W0
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 3759
0

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

Tzn.

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

lepiej użyć:

Kopiuj
    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

Koziołek
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Stacktrace
  • Postów: 6823
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.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.