2010-04-22 5 views
24

Penso di ottenere quello che cast non controllato significa (trasmettere da uno all'altro di un tipo diverso), ma cosa significa "Controllare" il cast? Come posso controllare il cast in modo da evitare questo avvertimento in Eclipse?Che cosa è il cast non controllato e come lo controllo?

+1

Invia il codice sorgente. –

+12

Non pubblicare il codice! Non permettergli di darti un pesce invece di insegnare a pescare :) No, sul serio, dovrebbe esserci una risposta generica per una domanda generica anche se la domanda viene posta in uno stile amatoriale. – Mike

risposta

28

Un cast non selezionato significa che si esegue (implicitamente o esplicitamente) il cast da un tipo generico a un tipo non qualificato o viceversa. Per esempio. questa riga

Set<String> set = new HashSet(); 

produrrà tale avviso.

Di solito c'è una buona ragione per tali avvertimenti, quindi dovresti provare a migliorare il tuo codice invece di sopprimere l'avviso. Citazione di Effective Java, 2a edizione:

Elimina ogni avviso non controllato che è possibile. Se si elimina lo stato di tutti gli avvisi, si ha la certezza che il proprio codice è tipicamente corretto, il che è molto buono per lo . Significa che non avrai uno ClassCastException in fase di runtime, e che lo aumenta la tua sicurezza sul fatto che il tuo programma si comporti come tu volevi.

Se non è possibile eliminare un messaggio di avviso, e si può dimostrare che il codice che provocato l'avviso è typesafe, allora (e solo allora) eliminare l'avviso con una @SuppressWarnings("unchecked") annotazione. Se si sopprimono gli avvertimenti senza aver prima provato che il codice è tipografico, si sta dando un senso di sicurezza solo falso. Il codice può essere compilato senza emettere alcun avvertimento, ma può ancora lanciare un ClassCastException in fase di esecuzione. Se, tuttavia, ignori gli avvisi non verificati che sai essere al sicuro (invece di sopprimerli), non visualizzerai quando si verifica un nuovo avviso che rappresenta un problema reale. Il nuovo avviso si perderà in mezzo a tutti i falsi allarmi che non hai messo a tacere.

Ovviamente, non è sempre facile eliminare gli avvisi come nel codice precedente. Senza vedere il tuo codice, non c'è modo di dire come renderlo sicuro.

+0

Che ne dite di questo cast incontrollato: 'FoodBag bag2 = new FoodBag ();' ' ((FoodBag ) bag2) .setFood (nuova CheeseSandwich());' da un tipo generico a un tipo generico? – Datoraki

+0

@Datoraki, potresti essere più specifico con la tua domanda? –

+19

-1 perché la risposta non affronta la sezione "come controllare il cast" della domanda. Ok, sappiamo che dovremmo controllare il cast, ** come ** lo facciamo? – Mike

39

Per ellaborate più su ciò che Peter ha scritto:

calchi da tipi non generici per i tipi generici può funzionare bene in fase di esecuzione, perché i parametri generici vengono cancellati durante la compilazione, quindi ci ritroviamo con un cast legittima. Tuttavia, il codice potrebbe non riuscire più tardi con un ClassCastException imprevisto a causa di un'assunzione errata riguardante il parametro type. Per esempio:

List l1 = new ArrayList(); 
l1.add(33); 
ArrayList<String> l2 = (ArrayList<String>) l1; 
String s = l2.get(0); 

L'avvertimento non controllato in linea 3 indica che il compilatore non è in grado di garantire la sicurezza di tipo più, nel senso che un ClassCastException inaspettato può occure somewere tardi. E questo succede alla riga 4, che esegue un cast implicito.

+5

Questa dovrebbe essere la risposta accettata – CodyBugstein

0

Un cast non controllato, a differenza del cast controllato, non controlla la sicurezza del tipo in fase di esecuzione.

Ecco un esempio basato sulla sezione Consider typesafe heterogenous containers del 3 ° ed.di "Effective Java" di Joshua Bloch, ma la classe contenitore è intenzionalmente rotto - esso memorizza e restituisce il tipo sbagliato:

public class Test { 

    private static class BrokenGenericContainer{ 
     private final Map<Class<?>, Object> map= new HashMap<>(); 

     public <T> void store(Class<T> key, T value){ 
      map.put(key, "broken!"); // should've been [value] here instead of "broken!" 
     } 

     public <T> T retrieve(Class<T> key){ 
//   return key.cast(map.get(key)); // a checked cast 
      return (T)map.get(key);  // an unchecked cast 
     } 

    } 

    public static void main(String[] args) { 
     BrokenGenericContainer c= new BrokenGenericContainer(); 
     c.store(Integer.class, 42); 
     List<Integer> ints = new ArrayList<>(); 
     ints.add(c.retrieve(Integer.class)); 
     Integer i = ints.get(0); 
    } 

} 


Se il retrieve() utilizza un getto incontrollato-(T)map.get(key) - esecuzione di questo programma sarà portare a ClassCastException alla riga Integer i = ints.get(0). Il metodo retrieve() completerà perché il tipo reale non è stata verificata in fase di esecuzione:

Exception in thread "main" 
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer 
    at Test.main(Test.java:27) 


Ma se il retrieve() utilizza un checked gettato - key.cast(map.get(key)) - eseguire questo programma porterà ad ClassCastException che si verificano a key.cast(map.get(key)) linea, perché il cast controllato scoprirà che il tipo è sbagliato e lancia l'eccezione. Il metodo retrieve() non porterà a termine:

Exception in thread "main" java.lang.ClassCastException: 
              Cannot cast java.lang.String to java.lang.Integer 
    at java.lang.Class.cast(Class.java:3369) 
    at Test$BrokenGenericContainer.retrieve(Test.java:16) 
    at Test.main(Test.java:26) 

Poca differenza può sembrare, ma nel caso con il cast incontrollato, un String realizzato con successo la sua strada in un List<Integer>. Nelle applicazioni del mondo reale, le conseguenze potrebbero essere ... beh, severe. Nel caso del cast selezionato, la mancata corrispondenza di tipo è stata scoperta il prima possibile.


Per evitare i calchi incontrollati avvertimento, @SuppressWarnings("unchecked") può essere utilizzato, se il programmatore è in realtà che il metodo è in realtà sicura. L'alternativa migliore è usare generici e cast controllati quando possibile.

come Joshua Bloch ha messo,

... avvertimenti incontrollati sono importanti. Non ignorarli.


Per ragioni di completezza, this offerte di risposta con le specifiche Eclipse.

Problemi correlati