Wenn die Typprüfung während der Kompilierung durchgeführt werden kann, wird die Typumwandlung während des Kompilierens durchgeführt und verursacht keinen Runtime Overhead.
Zum Beispiel
%Vor%Wird die Typumwandlung während der Kompilierung oder während der Laufzeit durchgeführt?
Und gibt es eine allgemeine Regel, um zu entscheiden, ob ein Typ-Casting vom Javac-Compiler oder von der VM ausgeführt wird?
Tatsächlich gibt es in diesem Fall drei Möglichkeiten:
javac
Compiler könnte die Optimierung durchführen. Ich erwarte, dass es Option 1. oder 2. ist, aber das könnte plattformspezifisch sein.
Tatsächlich ist der Bytecode auf meinem System nicht optimiert. Wenn eine Optimierung stattfinden soll, wird es der JIT-Compiler sein, um es zu tun. (Dies passt zu dem, was ich gehört habe ... dass die meisten Java-Bytecode-Compiler vor der Erzeugung von Bytecodes wenig Optimierung vornehmen.)
%Vor%Wenn ein laufendes Programm versucht, eine Objektreferenz auf einen anderen Typ zu übertragen, muss die virtuelle Maschine prüfen, ob der Typ, in den umgewandelt wird, die tatsächliche Klasse des referenzierten Objekts oder eines seiner Obertypen ist. Es muss die gleiche Art von Überprüfung durchführen, wenn ein Programm eine Operation ausführt.
In jedem Fall muss die virtuelle Maschine in die Klassendaten des referenzierten Objekts schauen. Wenn ein Programm eine Instanzmethode aufruft, muss die virtuelle Maschine eine dynamische Bindung ausführen: Sie muss die aufzurufende Methode nicht auf der Basis des Referenztyps, sondern auf der Klasse des Objekts auswählen. Zu diesem Zweck muss es erneut Zugriff auf die Klassendaten haben, die nur einen Verweis auf das Objekt enthalten.
Bearbeiten:
Der Java-Compiler ist nicht dafür verantwortlich, zu überprüfen, ob das Casting korrekt ist oder nicht, genau wie einige der Bindungen nur zur Laufzeit auftreten. Die Java Virtual Machine prüft zur Laufzeit, ob das eigentliche Referenzobjekt ein legitimes Objekt des neuen Typs ist. Wenn nicht, wird eine Laufzeitausnahme auftreten: ClassCastException.
Ich denke, es ist in beiden Phasen getan. Zur Kompilierungszeit wird der Compiler Sie zwingen, die richtigen Umwandlungen durchzuführen, um sicherzustellen, dass Sie die Typen nicht verwechselt haben, wie in jedem stark typisierten Code Sprache .
Wenn Sie jedoch Object
als Parameter in String
eingeben (was für Objekte funktioniert, die tatsächlich instanceof
String
sind), muss die JVM dennoch sicherstellen, dass die Implementierung erfolgt Die Klasse von Object
wird wirklich erweitert oder ist String
und Sie erhalten ClassCastException
, wenn dies nicht der Fall ist.
Wenn ich
kompiliert habe %Vor% und dekompiliert diesen Code mit javap -c Test
bei Java 7 (Windows 7 64bit) es gab mir dieses Ergebnis
Es scheint also so zu sein, dass der Compiler die Methode getChildVersion1
nicht so optimiert hat wie getChildVersion2
so neben dem Typ während der Kompilierung Zeit auch zur Laufzeit überprüft wird ( 9: checkcast #2
). Aber wie Stephen C erwähnt , kann es mit der Plattform (OS, Java-Version) in Verbindung stehen.
Für die Konvertierungen, die zur Laufzeit keinen Test erfordern, kann es sein, dass der Compiler einige Optimierungen vornimmt, um zu vermeiden, dass er zur Laufzeit umgewandelt wird.
Ich schlage vor, die JLS Kapitel 5. Conversions und Aktionen , um mehr über die Art der Conversions zu erfahren, die zur Laufzeit einen Test benötigen.
%Vor%Beispiel 5.0-1. Conversions bei Kompilierzeit und Laufzeit
5.1.6. Einschränken der Referenzkonvertierung :
Bei solchen Konvertierungen muss zur Laufzeit geprüft werden, ob der tatsächliche Referenzwert ein zulässiger Wert des neuen Typs ist. Wenn nicht, wird eine ClassCastException ausgelöst.
5.1.8. Unboxing-Konvertierung ; Die Konvertierung wird zur Laufzeit fortgesetzt.
Siehe auch: 5.5.3. Überprüfte Casts zur Laufzeit
Es ist nicht so einfach festzustellen, wann die Konvertierung stattgefunden hat:
%Vor% Das Ergebnis von javap -c Main
ist:
Wenn Sie die Methodendeklaration in public static Child getChild()
ändern, lautet das Ergebnis:
Sie sehen, dass das Ändern des Accessors die möglichen Optimierungen stark beeinflussen kann.