Podczas kompilacji plików z kodem Javy (pliki *.java) tworzone są instrukcje kodu bajtowego (pliki * class) które zostają wykonane przez interpreter kodu bajtowego. Jednak dobrze by było przyjrzeć się bliżej temu procesowi gdyż, co prawda cała kompilacja od strony praktycznej sprowadza się do wpisania polecenia w linii komend i jest przeprowadzana automatycznie przez kompilator, jednak obserwacja efektów jego działania należy już do użytkownika. Programista tworzący programy w Javie powinien wiedzieć jaka metodą powstaje kod maszynowy dla danej platformy, czyli innymi słowy jaka jest droga pomiędzy kodem źródłowym a kodem wykonywalnym. Musimy sobie jednak uświadomić, że użytkownik nie zawsze ma dostęp do kodu wykonywalnego na daną platformę, ponieważ taki kod może być generowany dopiero w trakcie uruchamiania programu. Aby wyjaśnić cały mechanizm generowania kodu maszynowego programu stworzonego w Javie dla danej platformy trzeba przedstawić kilka podstawowych zagadnień z nim związanych.
Kod maszynowy jest ciągiem liczb interpretowanych przez komputer, a konkretnie jego procesor w celu wywołania pożądanego efektu. Używanie serii liczb w celu wykonania określonego zadania nie jest jednak zbyt efektywne, a dla samego użytkownika niekomfortowe. Dlatego też stworzony został prosty język, który posiada proste instrukcje wywoływane z odpowiednimi parametrami lub wartościami. Tak przygotowany kod tłumaczony jest przez komputer na kod maszynowy. Opisywany wyżej język nosi nazwę assembler, a w przypadku Javy kod źródłowy kompilowany jest do pseudo-assamblera nazwanego b-kodem. Instrukcje napisane w B-kodzie, tłumaczone są na odpowiadające im ciągi liczb (kod maszynowy) w trakcie uruchomienia programu (klasy). W praktyce oznacza to, że jedna linia kodu napisanego w assamblerze zwykle generuje jedną linie kodu maszynowego. Dla porównania assemblera i pseudo-assamblera, poniżej przedstawiony jest fragment kodu w assemblerze, który wygląda następująco:
add eax, edx
mov ecx, eax
15