How can Java compiler successfully do the type cast at the runtime to Programmer (or Engineer)?
Der Java-Compiler Abgüsse nicht tun.
Eine Besetzung ist einfach eine Art, dem Compiler zu sagen: "Ich weiß mehr als du; vertrau mir." Der Compiler wird immer noch versuchen, Sie davon abzuhalten, Casts zu erstellen, die definitiv unsicher sind (wie zum Beispiel ein String
zu einem Integer
Casting), aber durch Casting übernehmen Sie die Verantwortung für die Typsicherheit weg vom Compiler. Sie sollten nur dann casten, wenn Sie durch die Semantik Ihres Codes/Systems wissen, dass es sicher ist.
Dieses spezielle Muster ist für das Abrufen heterogener Entitäten aus einem Repository üblich. aber es ist nicht typsicher.
Die Aufrufer der Methode ist es nur die Methode mit der "richtigen Art von ID" aufzurufen. Das Problem besteht darin, dass der Code nicht angibt, dass er fehlschlagen könnte.
Der Grund, warum dieses Muster mich immer ärgert, ist, dass es den tatsächlichen Ort verbirgt, an dem das Problem auftritt. Erinnern Sie sich daran, dass Java-Generika im Grunde genommen nur eine Auswahl von Casts sind. Dies bedeutet, dass die Methode „wirklich“ sieht wie folgt aus:
public static Employee findById(@NonNull factory,int employeeId) {
// There is actually no cast here!
return factory.findEmployeeById(employeeId);
}
Und der Anruf Seite sieht wie folgt aus:
// The cast is here instead!
SpecificEmployeeType e = (SpecificEmployeeType) findById(someId);
(Versuchen Sie schreiben den Code explizit wie diese, und vergleichen Sie den Bytecode mit dem generischen Version)
Als solche, während Sie die Warnung in der findById
Methode unterdrücken können, tritt die tatsächliche Ausnahme an der Aufruf-Site. Also ist die Warnung - die Anzeige, dass dort ein Problem auftreten kann - an der falschen Stelle.
Wenn Sie es explizit ohne die Generika schreiben, können Sie genau sehen, wo das Problem tatsächlich auftritt.
Die Leute sagen oft, dass sie Generika auf diese Weise verwenden wollen, weil es "sauberer" ist: Sie brauchen nicht die explizite Umwandlung oder Unterdrückung an jeder Call-Site. Persönlich möchte ich wollen, die extra Zeug dort: es macht es so aussehen, als gäbe es etwas Gefährliches dort (was gibt es!) Und damit Sie wissen, dass Sie besonders vorsichtig sein müssen.
Es ist auch erwähnenswert, dass Sie nicht@SuppressWarnings("unchecked")
, um Ihren Code hinzufügen - entweder in der findById
Methode oder an den Aufrufstellen - wenn Sie absolut sicher sein können, dass die Besetzung sicher ist.
Wie das Casting ist die Unterdrückung von Warnungen eine Möglichkeit, Verantwortung für Dinge zu übernehmen, die der Compiler nicht nachweisen kann. Indem Sie Warnungen natürlich unterdrücken, ignorieren Sie nur die Hilfe, die der Compiler zu bieten versucht. Wie bei jedem Vorsichtshinweis steht es Ihnen frei, dies zu ignorieren, aber es ist tollkühn, dies zu tun, ohne die Konsequenzen vollständig zu verstehen.
"Aber ich habe einige Schwierigkeiten, folgenden Code zu verstehen", das könnte sein, weil dieser Code eine allgemeine aber missbräuchliche Verwendung von Generika ist: es ist nicht Typ sicher. –