Irgendein Casting von javac?

9

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?

    
qinsoon 24.07.2012, 13:33
quelle

5 Antworten

2

Tatsächlich gibt es in diesem Fall drei Möglichkeiten:

  1. Der javac Compiler könnte die Optimierung durchführen.
  2. Der JIT-Compiler konnte die Optimierung durchführen.
  3. Der native Code des JIT-Compilers könnte Code enthalten, um eine Laufzeittypprüfung durchzufü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%     
Stephen C 24.07.2012, 13:47
quelle
1

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.

    
developer 24.07.2012 13:41
quelle
0

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.

    
Miquel 24.07.2012 13:41
quelle
0

Wenn ich

kompiliert habe %Vor%

und dekompiliert diesen Code mit javap -c Test bei Java 7 (Windows 7 64bit) es gab mir dieses Ergebnis

%Vor%

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.

    
Pshemo 24.07.2012 14:06
quelle
0

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.

  

Beispiel 5.0-1. Conversions bei Kompilierzeit und Laufzeit

%Vor%

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:

%Vor%

Wenn Sie die Methodendeklaration in public static Child getChild() ändern, lautet das Ergebnis:

%Vor%

Sie sehen, dass das Ändern des Accessors die möglichen Optimierungen stark beeinflussen kann.

    
alain.janinm 24.07.2012 13:49
quelle

Tags und Links