2012-09-15 12 views
8

Zastanawiam się, dlaczego wyjątek w następujący kod bajtowy (używane do throw Exception) jest powielony.Java Bytecode DUP

+0

po prostu dodać swoje trzy grosze. 'NEW' po prostu przydziela pamięć obiektu bez wywoływania jakiegokolwiek konstruktora,' INVOKESPECIAL' wywoła konstrukcję, ale wywołanie będzie wyskakiwane ze stosu 'this' wskaźnik i nie będzie wciskane nic (konstruktorzy zwracają' void'). Konwencjonalne kompilatory ukierunkowane na JVM będą generować sekwencję 'NEW/DUP/INVOKESPECIAL' w celu utworzenia nowego obiektu. Jest to wzór rozpoznawany przez JVM i może być specjalnie zoptymalizowany ... – csharpfolk

Odpowiedz

10

będę analizować ten wiersz po wierszu gdzie [] = new stos potem op służy:

  1. NEW stawia nowy IllegalArgumentException na stosie [SomeIllegalArgumentException]
  2. DUP duplikaty to [SomeIllegalArgumentException, SomeIllegalArgumentException]
  3. INVOKESPECIAL wyskakuje off Top One i inicjuje go nazywając to <startowych> metoda [SomeIllegalArgumentException] (Metoda startowy nie zwróci obiekt, aby umieścić z powrotem na stos, więc obiekt musi najpierw zostać powielony tak aby utrzymać go na stosie)
  4. ATHROW Zgłasza druga (duplikat wyłączyć jedną my zainicjowany) []
+7

Jest to łatwiejsze do zrozumienia, jeśli mniej myślisz o poppingu i przesuwaniu obiektów na stosie, a zamiast tego o referencjach. – oldrinb

6

W kodzie bajtowym obiekt jest najpierw tworzony przez klasę, a następnie wywoływany jest konstruktor na tym obiekcie. Podpis konstruktora kończy się V dla void, ponieważ zwraca wszystko. Oznacza to, że kopia oryginalnego odniesienia do obiektu musi być przechowywana na stosie (lub w zmiennej), aby można go było wywołać po wywołaniu konstruktora.

BTW Wewnętrzna nazwa konstruktora jest <init> i wewnętrzna nazwa dla statycznego kodu initialiser jest <clinit>

+1

To ma sens, dzięki! – LanguagesNamedAfterCofee

Powiązane problemy