2009-11-17 16 views

risposta

34

Essi espongono interfacce e contratto per il metodo diversi.

La prima dichiarazione deve restituire una raccolta il cui tipo di elementi è lo stesso della classe argomento. Il compilatore deduce il tipo di N (se non specificato). Così le due istruzioni seguenti sono valide quando si utilizza la prima dichiarazione:

Collection<Integer> c1 = getThatCollection(Integer.class); 
Collection<Double> c2 = getThatCollection(Double.class); 

La seconda dichiarazione non dichiara la relazione tra il tipo Collection argomento tornato alla classe argomento. Il compilatore presume che essi sono collegati, in modo che il cliente avrebbe dovuto utilizzare il tipo restituito come Collection<? extends Number>, indipendentemente da ciò che l'argomento è:

// Invalid statements 
Collection<Integer> c1 = getThatCollection(Integer.class); // invalid 
Collection<Double> c2 = getThatCollection(Double.class); // invalid 
Collection<Number> cN = getThatCollection(Number.class); // invalid 

// Valid statements 
Collection<? extends Number> c3 = getThatCollection(Integer.class); // valid 
Collection<? extends Number> c4 = getThatCollection(Double.class); // valid 
Collection<? extends Number> cNC = getThatCollection(Number.class); // valid 

Raccomandazione

Se davvero esiste una relazione tra la digitare tra l'argomento del tipo restituito e l'argomento passato, è molto meglio utilizzare la prima dichiarazione. Il codice cliente è più pulito come indicato sopra.

Se la relazione non esiste, allora è ancora meglio evitare la seconda dichiarazione. Avere un tipo restituito con un carattere jolly limitato costringe il client a utilizzare caratteri jolly ovunque, in modo che il codice client diventi rumoroso e illeggibile. Joshua Bloch enfizza che devi Avoid Bounded Wildcards in Return Types (diapositiva 23). Sebbene i caratteri jolly limitati nei tipi restituiti possano essere utili in alcuni casi, la bruttezza del codice del risultato dovrebbe, IMHO, prevalere sul vantaggio.

+3

+1 per una chiara spiegazione delle differenze. Piccolo cavillo: penso che tu esagerhi nell'assumere che il primo sia sempre la scelta migliore - direi "inutile dirlo" la scelta migliore dipenderebbe dal contesto. –

+0

@Steve Grazie! Ho aggiunto una spiegazione per cui la seconda affermazione deve essere evitata. – notnoop

+0

+1 Risposta impressionante! – Stephan

-3

In questo caso particolare, n. tuttavia, la seconda opzione è più flessibile poiché consente di restituire una raccolta che contiene elementi di un tipo diverso (anche se sarebbe anche un numero) rispetto al tipo contenuto nel parametro di raccolta.

Esempio concreto:

Collection<? extends Number> getRoot(Class<? extends Number> number){ 
    ArrayList<Integer> result=new ArrayList<Integer>(); 
    result.add(java.util.Math.round(number); 
    return result) 
}