İlk öncə Compiler və Interpreter anlayışları ilə tanış olaq:
Tərtib etmə (compilation - kompilyasiya) və şərh etmə (interpretation) - proqramlaşdırma dilləri dünyasının əsas anlayışlarındandır. Adətən, dillər də kompilyasiya edilən və şərh edilən olmaqla iki yerə bölünürlər. Məsələn:
Kompilyasiya edilən (tərtib edilən) - Fortan, C, C++, Pascal, Haskell, Rust, Go
Şərh edilən - JavaScript, PHP, Python, Ruby
Kompilyasiya etmə - insanın yazdığı mənbə kodun (source code) maşının anlayacağı formaya çevrilməsidir. Özümüzün elə bir kod yazmağımız mümkünsüz qədər çətindir, ona görə də bu işi compiler edir və bizim yazdığımız insanın anlayacağı kodu maşının anlayacağı koda çevirir. Bu zaman çalışan - bizim yazdığımız kod deyil, maşın dilinə çevrilən kod olacaq. O kodlara “executable”, yəni “icra edilə bilən” deyilir, yəni onlar artıq icra oluna biləcək vəziyyətə gəlirlər.
Bir də şərh olunan dillər var. O dillərdə bir son kod yaratmırıq, birbaşa bizim yazdığımız kod icra edilir. O icra edilməyə də “şərh edilmə” (interpretation) deyilir. Burada source code, yəni mənbə kodu maşın dilinə çevrilmədən interpreter (şərhçi) tərəfindən birbaşa maşın dilində olan koddakı bloklar çağrılaraq icra edilir, yəni şərh edilir. Compiler-də olduğu kimi bir son kod yoxdur.
Source kodun compile olunduğu zamana - compile-time deyilir, icra edildiyi, “run” edildiyi zamana isə run-time deyilir.
Compiled, yəni kompayl edilən dillər çox sürətlidirlər, çünki runtime-a iş buraxmırlar, işin çoxu kompilyasiyada edilir. Amma Interpreted, yəni şərh edilən dillər sistem dili deyil. Compiled dillərin 1-2 saniyədə tapdığı şeyi Interpreted dil 40 saniyədə tapa bilər. Çünki bütün işləri runtime-da edir. Amma Compiled dillər öncə edir, sonra onu çalışdırır. Buna görə də bu iki növ dil arasında fərqlər var. Compilation - xətadan təmizlənmiş kod hazırlayar, çünki runtime-a az iş saxlayır, bütün xətaların adətən kompilyasiya zamanı çıxmasını gözləyib, xəta varsa, onu düzəldib elə davam edərik. Bununla da runtime-a daha təmiz və doğru bir kod gedər, çünki çıxa biləcək əsas xətaları compiler bizə göstərdiyi üçün onları artıq düzəltmiş oluruq. Amma bunun da mənfi cəhəti odur ki, o platformadan asılıdır, eyni mənbə kodunu (source code) hər fərqli platforma üçün yenidən compile etmək lazım olur.
Amma Interpreted dil olan Python-da bir source kodu birinə versək, onu çalışdırması bəs edir. Çünki hər şeyi həmin an görüntü rejimində yaradır. Amma bunun da mənfi tərəfləri var:
- Xətalar runtime-da ortaya çıxır, ona qədər kodda səhvimiz olduğunun fərqində olmaya bilərik. Bu kod xətaya açıqdır.
- Kodun çox sürətli olması mümkün deyil. Bununla operativ sistem, realtime bir kod yaza bilmərik.
Müsbət tərəfi isə odur ki, platformadan asılı deyil. Python-da yazılmış bir kod, Python-un olduğu hər yerdə işləyər. Amma Compiled dillər isə öncə compile edilir, o platformaya özəl olaraq yaranır, ondan sonra işləyir.
Dillər arasındakı bu fərqlər Just-in-Time Compiler texnologiyası sayəsində azaldılmışdır. Just-in-Time Compiler edib, Python kodunun sürətini C++ sürətinə yaxınlaşdıra, onu o andaca görüntü rejimində compile edə bilərik.
Java bunlardan hansına aiddir?
Java həm Compiled, həm də Interpreted dildir. Yəni Compiled olmaqla, həm aktiv olmağa, həm də Interpreted olmaqla, platformadan azad olmağa çalışır. Java source, yəni mənbə kodları (.java faylında olan kodlar) birbaşa maşın dilindəki koda çevrilməz, bayt kodlardan (byte code) əmələ gələn .class ilə bitən falyllara çevrilir. Baytkod isə runtime-da JVM tərəfindən şərh edilir.
Bir .java faylını compile etdiyimiz zaman maşının anlayacağı mənada bir son kod yaratmırıq, yəni o maşın kodu deyil. Amma o artıq .java kodu da deyil, compile edilmiş bir ara koddur və ona baytkod deyirik, onu yalnız JVM anlayır. JVM-i ayağa qaldırıb ona bayt kodumuzu daxil etsək, o, onu oxuyub icra edir. Bununla da xətadan təmizlənmiş həm bir ara kod, həm də platformadan azad olmasını əldə edirik. Java-çıların əsasən bağlı olduqları yeganə platforma JVM-dir, yəni biz JVM-ə compile edirik, maşına deyil. JVM-ə compile edəndə o da maşına interprete edir. Java-nın işləyəcəyi bütün mühitlərdə JVM olmalıdır. Bayt kodlardan ibarət olan .class faylı platformadan asılı deyil və JVM-in olduğu hər hansı bir yerdə JVM tərəfindən icra edilir.
Biz .java faylını, yəni source kodu insanlarla paylaşmağa məcbur deyilik, lazım gəldiyi zaman .class faylını insanlarla paylaşarıq.
JVM - compile edilmiş Java kodlarını, baytkodları icra edən sistemdir. Adətən, içində Just-in-Time Compiler ehtiva edir. JRE-nin (Java Runtime Environment) əsas hissəsidir. Java-nın işləyəcəyi hər bir platformada JVM qurulmalıdır.