2009-10-02 15 views
7

Ho il seguente codiceUso generici provoca incontrollato avvertimento conversione

String innerText = null; 
innerText = this.getException(detail.getChildElements()); 

causando questo avvertimento

sicurezza Tipo: L'espressione di tipo Iterator ha bisogno di conversione incontrollato di conformarsi a Iterator

Il metodo di riferimento è

private String getException(Iterator<OMElementImpl> iterator) { ... } 

L'altro metodo, getChildElements(), si trova in un file JAR che non riesco a toccare. Non ci sono altri avvisi o errori.

Da usare Google, sembra che il solito modo per sbarazzarsi di questo tipo di avvertimento è

@SuppressWarnings("unchecked") 
String innerText = this.getException(detail.getChildElements()); 

perché il compilatore non può garantire la sicurezza prima del tempo, ma io preferirei evitare di utilizzare SuppressWarnings se possibile ... c'è un modo migliore?

EDIT: getChildElements() è documentato here

+5

Basta essere contento che i generici Java consentano di compilare il codice. Personalmente lascerei lì l'avviso - è un avvertimento perfettamente valido. –

risposta

16

È può eliminare l'avviso, ma se lo fate, si fa affidamento al 100% sulla libreria di terze parti, e scartando la garanzia di Java tipi generici: che qualsiasi ClassCastException generato in fase di esecuzione si verificherà proprio in un cast esplicito.

Il nostro standard di codifica è quello di eliminare gli avvisi solo quando siamo in grado di dimostrare il codice è SICURO tipo — e trattiamo tutte le chiamate al di fuori del pacchetto come una scatola nera, e non si basano su eventuali commenti sul contenuto di un raccolta grezza. Quindi, la soppressione è estremamente rara. Di solito, se il codice è sicuro, il compilatore può determinarlo, anche se a volte dobbiamo dargli un po 'di aiuto. Le poche eccezioni riguardano array di tipo generico che non "scappano" da un contesto privato.

Se non ci si fida completamente della libreria di terze parti, creare una nuova raccolta e aggiungere i contenuti dopo averli convertiti in OMEElementImpl. In questo modo, se c'è un bug nella libreria, lo scopri subito, piuttosto che avere un codice molto distante nel tempo e nello spazio esplodere con uno ClassCastException.

Ad esempio:

Iterator<?> tmp = detail.getChildElements(); 
Collection<OMElementImpl> elements = new ArrayList<OMElementImpl>(); 
while (tmp.hasNext()) 
    elements.add((OMElementImpl) tmp.next()); /* Any type errors found here! */ 
String innerText = getException(elements.iterator()); 

Ricordate, i generici non sono stati inventati per rendere il codice guardare piuttosto e richiedono meno di battitura! La promessa di generici è questa: Il tuo codice è sicuro di essere sicuro per il tipo se viene compilato senza avvisi. Ecco fatto. Quando gli avvertimenti vengono ignorati o soppressi, il codice senza operatore di cast può sollevare misteriosamente uno ClassCastException.


Aggiornamento: In questo caso, in particolare, sembra estremamente rischioso supporre che il risultato di getChildElements è un iteratore di OMElementImpl. Nella migliore delle ipotesi, si potrebbe supporre che siano OMElement, e questo è solo implicito dalla classe, non in particolare sul metodo.

+0

Verificare i contenuti di una raccolta restituita da una libreria di terze parti come questa è un buon consiglio. –

+0

In alternativa alla creazione di una nuova raccolta, consultare 'Iterables.transform' in Google Collections http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Iterables.html#transform (java.lang.Iterable,% 20com.google.common.base.Function) –

+0

Beh, sono un nuovo sviluppatore junior e mi è stato assicurato che è giusto fare l'ipotesi in questo caso particolare; Io (e il mio capo tecnico, per quella questione) odio solo vedere la piccola icona di avviso. + 1/accettato per dare un buon consiglio generale, però. – Pops

Problemi correlati