Wir sind gerade dabei, eine Anwendung von Java 7 nach Java 8 zu migrieren. Nachdem ich einige Kompilierungsprobleme behoben hatte, stieß ich auf ein Problem, das der folgenden Frage ähnelte: ClassCast Error: Java 7 vs Java 8.Wie erkennen Sie mehrdeutige Methodenaufrufe, die eine ClassCastException in Java 8 verursachen würden?
, hier Zusammengefasst ist ein Beispielcode, der das Problem zeigt:
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
}
}
Die Idee war, dass wir stoßen würde, dass der Anrufer den erwarteten Typ kennt, und dies würde ihm eine explizite Umwandlung (Ich vermeide sag nicht, das war eine gute Idee ...). In vielen Fällen erwartet der Aufrufer nur eine Object
, also gab es überhaupt keine implizite Besetzung.
Wie in der obigen Frage angegeben, funktionierte das String.valueOf
Beispiel in Java 7 gut, da keine Typrückschlüsse vorlagen, daher wurde Object
angenommen. In Java 8 wählt der Compiler nun den spezifischsten Typ (hier char[]
), der zur Laufzeit einen ClastCastException
verursacht. Das Problem ist, dass wir etwa 350 Aufrufe dieser getVal
Methode haben. Gibt es eine Möglichkeit, überladene Methodenaufrufe zu erkennen, die sich zwischen Java 7 und Java 8 unterscheiden würden? I.E. erkennen, wenn der Java 8-Compiler eine andere Methode als den Java 7-Compiler auswählt.
Wir hatten eine ähnliche Methode, die auch in Hunderten von Orten aufgerufen wurde. Ich ersetzte es, indem ich zusätzliche "Class clazz" Parameter einführte. Auf diese Weise können Sie eine explizite Fehlerbehandlung durchführen: entweder null zurückgeben oder eine spezifischere Ausnahme auslösen. Ich habe das manuell nur eine halbe Stunde lang ausgegeben. Ich rate Ihnen, das Gleiche zu tun. Ich weiß nicht, wie ich es automatisieren soll, daher ist dies keine Antwort auf Ihre Frage. –
Es gibt eine einfache Antwort: * "ungeprüfte" Warnungen nicht unterdrücken *. Sie sagen dir bereits, dass dein Code falsch ist. Wenn Sie Ihren Code jetzt reparieren möchten, weil es zu spät ist, suchen Sie einfach nach Vorkommen von '@SuppressWarnings (" unchecked ")' ... – Holger
@Holger Könnten Sie das bitte meinem Kollegen sagen, als er das im Jahr 2011 implementiert hat? Ich wusste schon vorher, dass es eine schlechte Idee war (obwohl nicht so schlecht wie jetzt in Java 8). Außerdem gibt es beim Methodenaufruf selbst keine '@ SuppressWarnings', sondern nur die Deklaration von 'getVal'. Wenn Sie diese Anmerkung hier entfernen, werden die problematischen Verwendungen nicht angezeigt. –