Siamo attualmente in fase di migrazione di un'applicazione da Java 7 a Java 8. Dopo aver risolto alcuni problemi di compilazione, mi sono imbattuto in un problema simile alla seguente domanda: ClassCast Error: Java 7 vs Java 8.Come rilevare chiamate di metodi ambigue che potrebbero causare ClassCastException in Java 8?
Per riassumere, ecco un esempio di codice che mostra il problema:
public class Test {
public static void main(String[] args) {
System.out.println(String.valueOf(getVal("xxx"))); // 7: prints the result, 8: Exception
}
@SuppressWarnings("unchecked")
public static <T> T getVal(String param) {
// do some computation based on param...
return (T) result; // actual return type only depends on param so the caller knows what to expect
}
}
L'idea era che avremmo spinta che il chiamante conosce il tipo previsto, e questo lo eviterebbe un cast esplicito (I non dire che questa era una buona idea ...). In molti casi, il chiamante si aspetta solo un Object
quindi non c'è stato alcun cast implicito.
Come indicato nella domanda precedente, l'esempio String.valueOf
ha funzionato correttamente in Java 7 perché non era presente alcuna inferenza di tipo, pertanto è stato assunto Object
. Ora in Java 8, il compilatore sceglie il tipo più specifico (qui char[]
), che causa uno ClastCastException
in fase di esecuzione.
Il problema è che abbiamo circa 350 chiamate di questo metodo getVal
. C'è un modo per rilevare chiamate con metodo sovraccarico che differiscono tra Java 7 e Java 8? I.E. rileva quando il compilatore Java 8 seleziona un metodo diverso dal compilatore Java 7.
Abbiamo avuto un metodo simile che è stato anche chiamato in centinaia di posti. L'ho sostituito introducendo un ulteriore parametro 'Classe clazz'. In questo modo puoi avere una gestione esplicita degli errori: restituire null o lanciare qualche eccezione più specifica. L'ho fatto manualmente spendendo mezz'ora. Ti consiglio di fare lo stesso. Non so come automatizzarlo, quindi questo non è qualificato come risposta alla tua domanda. –
C'è una risposta semplice: * non sopprimere gli avvertimenti "deselezionati" *. Ti hanno già detto che il tuo codice è sbagliato. Se vuoi correggere il tuo codice ora che è troppo tardi, cerca le occorrenze di '@SuppressWarnings (" unchecked ")' ... – Holger
@Holger Potresti dirlo al mio collega quando ha implementato questo nel 2011? ;-) Sapevo già che era una cattiva idea in primo luogo (anche se non così male come lo è ora in Java 8). Inoltre, non ci sono '@ SuppressWarnings' sulla chiamata al metodo, è solo nella dichiarazione di' getVal'. La rimozione di questa annotazione qui non mostrerà quindi nessuno degli usi problematici. –