Learn · concepts

Java Sınıf Yükleyicisi Nedir?

Bir sınıf yükleyici, çalışma zamanında Java sınıflarını JVM'ye bulur ve yükler. İşte bunların nasıl çalıştığı, hiyerarşinin neden önemli olduğu ve modların bunlara neden bağlı olduğu.

TRtrolPublished 4 min read

Bir sınıf yükleyici, Java çalışma zamanının bir sınıf dosyasını bulan ve onu JVM'ye yükleyen kısmıdır. Kodunuz her defasında bir türle ilk kez etkileşime girdiğinde, JVM bir sınıf yükleyicisine sorar: "Bana bu sınıfı bul." Yükleyici, bayt kodunu bulur, okur ve JVM sınıfı bellekte tanımlar. Bu mekanizma normal Java programlarında görünmez, ancak mod çerçevelerinin Minecraft'ı yamalamak için kullandığı tam bağlantı noktasıdır.

Bir sınıf yükleyicisi aslında ne yapar

Bir sınıf yükleyici, bir sınıf adını çalışan JVM içindeki kullanılabilir bir sınıfa dönüştürür. Bir tür için talepte bulunursunuz, yükleyici eşleşen .class dosyasını bulur (veya oluşturur), doğrular ve bağlar ve sınıf kullanıma hazırdır.

İş üç adımda gerçekleşir:

  1. Bul — Yükleyici, adlandırılan sınıf için bayt kodunu (bir JAR'dan, diskten, ağdan veya anında oluşturulmuş olarak) bulur.
  2. Doğrula ve bağla — JVM, bayt kodunun geçerli olup olmadığını kontrol eder ve diğer sınıflara yapılan referansları çözer.
  3. Kullan — Sınıf kullanıma hazırdır ve programınız onu örnekleyebilir.

İşte Java programlarının derleme zamanında hiç bahsedilmemiş kodu çalışma zamanında dinamik olarak yükleyebilmesinin nedeni. Yükleyicinin bulması için sınıf adı yeterlidir.

Sınıf yükleyici hiyerarşisi

Sınıf yükleyicileri bir üst-çocuk zinciri şeklinde düzenlenmiştir ve bunların çoğu önce üst öğesine sorar. Standart bir Java uygulaması üç yerleşik sınıf yükleyicisine sahiptir:

YükleyiciYüklemelerAmaç
BootstrapTemel Java çalışma zamanı sınıflarıjava.lang.Object gibi temel türlerin her zaman aynı olmasını sağlar
PlatformÇekirdek dışında standart kütüphane modülleriJava modülleri ve uzantıları
UygulamaProgramınızın kendi sınıflarıProgramınızın belirttiği sınıf yolu

Uygulama yükleyicisi bir sınıf için istendiğinde, normalde önce yukarıya devretmeye başlar. Platform yükleyicisini sorar, platform yükleyicisi de bootstrap yükleyicisini sorar, bu da onu yüklemeye çalışır. Sadece hiçbir üst yükleyici yükleyemezse çocuk yüklemeye çalışır. Bu devretme modelidir ve aynı sınıfın farklı adlar altında iki kez yüklenmesini engeller.

Sınıf kimliği ve nasıl çalışır

Bir sınıf hem adıyla hem de onu tanımlayan yükleyici tarafından tanımlanır. İki farklı yükleyici de com.example.MyClass adlı bir sınıfı yükleyebilir ve JVM bunları tamamen farklı türler olarak ele alır. Bu anlaşılması zor gelebilir, ancak Java'nın yapabileceği her ilginç şeyin temelini oluşturur.

Bootstrap Loader: java.lang.Object (the core Object)
Application Loader: java.lang.Object (if somehow re-loaded by app loader)
→ Two different types, same name
→ This breaks your program, which is why delegation prevents it

Özel sınıf yükleyicileri

Programlar kendi sınıf yükleyicilerini tanımlayabilir. Özel bir yükleyici, herhangi bir yerden bayt kodu okuyabilir: bir JAR dosyası, ağ, bir veritabanı veya anında oluşturduğu veya dönüştürdüğü bayt kodu. İşte nasıl:

  • Eklenti sistemleri, derleme zamanında haberdar olmadan kodu dinamik olarak yükler.
  • Uygulama sunucuları (Tomcat, JBoss), her biri kendi sınıf yükleyicisine sahip olmak üzere aynı JVM içinde birden fazla uygulama çalıştırır.
  • Minecraft modları, yüklendikçe oyun sınıflarını yamalar.

Bunun Minecraft modları için neden önemli olduğu

Modlar özel sınıf yüklemesi nedeniyle var olurlar. Minecraft için bir mod yükleyici, oyunun kendi özel sınıf yükleyicisi aracılığıyla başlamasını sağlar, böylece oyun sınıflarını yüklenirken görebilir ve değiştirebilir. Bu kesme noktası sihrin gerçekleştiği yerdir.

Bir yükleyici disk ve JVM arasına oturduğunda, JVM tanımlamadan hemen önce bir sınıfı dönüştürebilir:

Disk: obfuscated Minecraft class
    ↓
Mod Loader (custom classloader)
    ↓ [bytecode transformation happens here]
    ↓
JVM: defines the patched class
    ↓
Memory: game runs with mods active

Bir mod, bir oyun yöntemini yeniden yazabilir, yeni davranış ekleyebilir, alanlar ekleyebilir; oyun JAR dosyasını diskte değiştirmeden. JVM'nin sonunda çalıştırdığı sınıf, mod çerçevesi tarafından değiştirilen sınıftır. Fabric, Forge ve diğer mod yükleyicileri Minecraft'ı tam olarak bu şekilde yamalar.

Tembel yükleme

Sınıflar başlangıçta yüklenmez. JVM, bir sınıf ilk kez kullanıldığında onu yükler. Buna tembel yükleme denir:

Program starts → JVM doesn't load String class yet
User calls System.out.println() → String is needed → Loader loads it

Bu, bir sınıf yükleyicisinin yalnızca kodunuzun temas ettiği sınıfları bulması ve yüklemesi gerektiği anlamına gelir. Kullanılmayan sınıflar belleğe girmez. Bunun nedeni, Minecraft başlangıcınızın bir süre alabilmesidir (modlar çok sayıda sınıf ekler), ancak sonsuza kadar donmamasıdır.

Sıkça Sorulan Sorular