Nie rozumiem następującego tekstu ... Czy to znaczy, że <clinit>
jest dla pustych konstruktorów? Dlaczego ważne jest, aby mieć dwie różne wersje?
https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html
2.9. Special Methods
Na poziomie wirtualnej maszyny Javy każdy konstruktor (§2.12) pojawia się jako metoda inicjalizacji instancji o specjalnej nazwie
<init>
. Ta nazwa jest dostarczana przez kompilator. Ponieważ nazwa<init>
nie jest poprawnym identyfikatorem, nie można jej używać bezpośrednio w programie napisanym w języku programowania Java. Metody inicjowania instancji mogą być wywoływane tylko w wirtualnej maszynie Javy za pomocą instrukcji invokespecial i mogą być wywoływane tylko w przypadku niezainicjowanych instancji klas. Metoda inicjalizacji instancji przyjmuje uprawnienia dostępu (§ 2.7.4) konstruktora, z którego została wyprowadzona.Klasa lub interfejs ma co najwyżej jedną metodę inicjalizacji klasy lub interfejsu i jest inicjowana (§2.17.4) przez wywołanie tej metody. Metoda inicjalizacji klasy lub interfejsu jest statyczna i nie pobiera żadnych argumentów. Ma specjalną nazwę
<clinit>
. Ta nazwa jest dostarczana przez kompilator. Ponieważ nazwa<clinit>
nie jest poprawnym identyfikatorem, nie można jej używać bezpośrednio w programie napisanym w języku programowania Java. Metody inicjowania klas i interfejsów są wywoływane niejawnie przez wirtualną maszynę języka Java; nigdy nie są wywoływane bezpośrednio z żadnej wirtualnej maszyny Javy w konstrukcji w2, ale są wywoływane tylko pośrednio w ramach procesu inicjalizacji klasy.
CL
?<init>
oznacza konstruktor,<clinit>
oznacza statyczny inicjator : „Statyczne bloki inicjalizacyjne” w samouczku języka Java , inicjator statyczny w języku Java .źródło
Różnica między
<init>
i<clinit>
polega na tym, że<init>
jest używany w przypadku metod konstruktora, które inicjują wystąpienie obiektu, podczas gdy<clinit>
jest używany do inicjowania samego obiektu klasy. Na przykład inicjalizacjastatic
pól na poziomie klasy jest wykonywana<clinit>
podczas ładowania i inicjalizacji klasy.źródło
Wystarczy dodać Jeśli używasz metody Class.forName, to tylko inicjalizuje ona klasę. Więc z tej metody wywołuje tylko Clinit, a gdy użyjesz newInstance na obiekcie zwróconym przez forName, wywoła init w celu zainicjowania instancji. Możesz użyć poniższego kodu, aby zobaczyć go podczas debugowania.
public class ByteCodeParent { public static String name="ByteCode"; public ByteCodeParent() { System.out.println("In Constructor"); } static { System.out.println("In Static"); } { System.out.println("In Instance"); }
Aby przetestować, użyj
Class<ByteCodeParent> bcp2 =(Class<ByteCodeParent>) Class.forName("ByteCodeParent"); ByteCodeParent bcp4= bcp2.newInstance();
źródło