Czym jest bytecode JVM? Wyjaśnienie plików klas Java

Kod bajtowy JVM to zwięzły zestaw instrukcji, na którym działa Java Virtual Machine. Dowiedz się, jak działają pliki .class, dlaczego mody przepisują kod bajtowy i jaką rolę pełni ASM.

Conceptsby trqUpdated June 4, 2026
Key takeaways
  • Bajtkod JVM to kompaktowy zestaw instrukcji, który wykonuje Wirtualna Maszyna Java.
  • Kompilator Javy generuje bajtkod w plikach .class, a nie natywny kod maszynowy.
  • Ten sam plik .class działa na każdej platformie z uruchomionym środowiskiem Java, co jest celem tego formatu.
  • Mody przepisują bajtkod, aby zmieniać skompilowaną grę, nie mając do tego dostępu do jej kodu źródłowego.

Kod bajtowy JVM to zestaw instrukcji, który wykonuje Wirtualna Maszyna Java. Podczas kompilacji kodu źródłowego Java, kompilator nie generuje kodu maszynowego dla Twojego procesora. Generuje on kod bajtowy, kompaktowy i przenośny format przechowywany w plikach .class. JVM odczytuje te instrukcje w czasie działania i przekształca je na kod natywny w trakcie działania.

Gdzie pasuje Opal

Opal to mod Fabric, a narzędzia modyfikacyjne, na których się on opiera, wykonują pracę z bytecode za Ciebie, więc nie musisz ręcznie manipulować opkodami. Jeśli chcesz dodać zachowanie w czystym JavaScript, zobacz wprowadzenie do skryptów.

Jak kod źródłowy staje się bytecode

Plik .java to tekst, który pisze człowiek. Plik .class to skompilowany wynik, który uruchamia JVM. Kompilator czyta twój kod źródłowy, sprawdza go i zapisuje jeden plik .class na każdą klasę, zawierający instrukcje bytecode oraz pulę stałych, tabele metod i inne metadane.

Bytecode nie jest powiązany z żadnym konkretnym procesorem. Ten sam plik .class działa na Windows, macOS, Linux lub czymkolwiek z uruchomionym Java Runtime, ponieważ to JVM jest warstwą, która wie, jak wykonywać instrukcje na lokalnej maszynie. Taka przenośność jest celem tego formatu.

Jak wyglądają instrukcje

Bytecode to zestaw instrukcji oparty na stosie. Większość operacji umieszcza wartości na stosie operandów, zdejmuje je i umieszcza wynik. Nie ma alokacji rejestrów, o których trzeba by myśleć; model jest celowo prosty, aby JVM mogła go szybko zweryfikować i wykonać.

Kilka przykładowych opcode'ów daje wyobrażenie:

OpcodeCo robi
iloadUmieszcza lokalną zmienną int na stosie
iaddZdejmuje dwa inty ze stosu, umieszcza ich sumę
invokevirtualWywołuje metodę instancyjną
getfieldOdczytuje pole instancyjne
returnZwraca z metody

Rzadko czytasz lub zapisujesz je ręcznie. Narzędzia je generują i konsumują, dlatego biblioteka taka jak ASM jest przydatna.

Dlaczego bytecode ma znaczenie dla modyfikacji

Kod bajtowy ma znaczenie, ponieważ umożliwia zmianę zachowania bez dostępu do oryginalnego kodu źródłowego. Mod Minecraft prawie nigdy nie posiada kodu źródłowego gry. Posiada natomiast skompilowaną grę na dysku. Aby dodać lub zmodyfikować funkcję, mod odczytuje istniejący kod bajtowy, przepisuje go i przekazuje wynik z powrotem do JVM podczas ładowania klas.

Właśnie tak działają frameworki patchowania, wstrzykując haki do metod, których nie posiadają. Znajdują odpowiednie miejsce w skompilowanej metodzie i wplatają wywołanie kodu modu. Praca na poziomie kodu bajtowego pozwala modowi dołączyć do gry, mimo że nigdy nie widzi ani jednej linii oryginalnej Javy.

Gdzie pasuje ASM

ASM to biblioteka Java do odczytu, zapisu i transformacji kodu bajtowego. Parsuje plik .class na zdarzenia lub drzewo, umożliwia modyfikację instrukcji i emituje poprawny plik .class. Jest mały, szybki i działa blisko surowego formatu, dlatego narzędzia do modowania wyższego poziomu budują na nim, zamiast samodzielnie parsować pliki klas.

Większość modderów nigdy nie wywołuje ASM bezpośrednio. Używają warstwy wyższego poziomu, która ukrywa opkody i udostępnia bardziej przyjazny sposób wyrażenia „uruchom mój kod na początku tej metody”. Pod spodem ta warstwa edytuje kod bajtowy, często za pomocą ASM.

FAQ