2016-08-14 12 views
12

wiem, że nie było podobne pytanie już pisał, chociaż myślę, że mój jest nieco inna ...Różnica między ograniczone parametru Typ i górną granicę Wildcard

Załóżmy, że mamy dwie metody:

// Bounded type parameter 
private static <T extends Number> void processList(List<T> someList) { 

} 

// Upper bound wildcard 
private static void processList2(List<? extends Number> someList) { 
    // ... 
} 

O ile mi wiadomo, obie metody przyjmują argumenty, które są List typu lub List of lub List zz podtypu.

Ale jaka jest różnica między tymi dwoma metodami?

Odpowiedz

6

Istnieje kilka różnic między tymi dwoma składni podczas kompilacji:

  • z pierwszym składni, można dodać elementy do someList ale z drugiej, nie można. Jest to powszechnie znane jako PECS i mniej powszechnie znane jako PUT i GET prinicple.
  • Pierwszą składnią jest uchwyt do parametru typu T, dzięki czemu można go używać do wykonywania czynności, takich jak definiowanie zmiennych lokalnych w metodzie typu T, rzutowanie odwołania do typu T, metody wywoływania, które są dostępne w klasie reprezentowanej przez T itp. Ale z drugą składnią, nie masz uchwytu do typu, więc nie możesz tego zrobić.
  • Pierwsza metoda może zostać wywołana z drugiej metody do przechwycenia symbolu wieloznacznego. Jest to najczęstszy sposób na użycie wieloznacznika capture a za pomocą metody pomocniczej.

    private static <T extends Number> void processList(List<T> someList) { 
        T n = someList.get(0); 
        someList.add(1,n); //addition allowed. 
    } 
    
    private static void processList2(List<? extends Number> someList) { 
        Number n = someList.get(0); 
        //someList.add(1,n);//Compilation error. Addition not allowed. 
        processList(someList);//Helper method for capturing the wildcard 
    } 
    

Należy pamiętać, że leki generyczne są od kompilacji cukier czas, te różnice w szerszym zakresie są ograniczone tylko do kompilacji.

0

mogę myśleć o poniższych różnicami:

a) Modyfikacja listy wewnątrz metody, należy rozważyć poniżej kod:

private static <T extends Number>void processList(List<T> someList) 
{ 


    T t = someList.get(0); 
    if (t.getClass() == Integer.class) 
    { 
     Integer myNum = new Integer(4); 
     someList.add((T) myNum); 
    } 

} 

// Upper bound wildcard 
private static void processList2(List<? extends Number> someList) 
{ 
    Object o = someList.get(0); 
    if (o instanceof Integer) 
    { 
     Integer myNum = new Integer(4); 
     someList.add(myNum); // Compile time error !! 
    } 
} 

Z zamiennika nie można dodać elementy do listy! Kompilator mówi, że nie wie, co to jest myNum. Ale w pierwszej metodzie można dodać Integer, najpierw sprawdzając, czy T jest Integer, bez błędu czasu kompilacji.

b) Pierwsza metoda nazywana jest metodą ogólną. Jest on zgodny ze składnią zdefiniowaną dla generic method. Górne ograniczenia określone w definicji metody są używane do oznaczania typów parametrów ograniczających.

Drugi NIE jest koniecznie nazywany metodą ogólną, jest to normalna metoda, która akceptuje ogólny parametr . Symbol wieloznaczny ? z extends słowem kluczowym jest używany jako środek relaksujący typy, które metoda może zaakceptować.

0

Różnica jest po stronie kompilatora. Na pierwszym można użyć typu (aby rzucić coś lub użyć go jako powiązanego, aby na przykład wywołać inną metodę), podczas gdy na drugim nie można go użyć.

0

Jeśli chcesz użyć informacji o typie, przejdź do ograniczonego zakresu. W przypadku symbolu wieloznacznego argument będzie wyświetlany jako obiekt ogólny i nie będzie można wywoływać metod opartych na tym typie.

public static <T extends Object> ListIterator<T> createListIterator(ListIterator<T> o) 
{ 
    return new ListIteratorAdaptor<T>(o); 
} 
Powiązane problemy