Java Sınıf Yükleyicisi
Java ClassLoader soyut bir sınıftır. Bir şeye ait java.lang paket. Farklı kaynaklardan sınıfları yükler. Java ClassLoader, sınıfları çalışma zamanında yüklemek için kullanılır. Başka bir deyişle JVM, bağlama işlemini çalışma zamanında gerçekleştirir. Sınıflar ihtiyaca göre JVM'ye yüklenir. Yüklenen bir sınıf başka bir sınıfa bağlıysa o sınıf da yüklenir. Bir sınıfın yüklenmesini istediğimizde, sınıfı ebeveynine devreder. Bu şekilde çalışma zamanı ortamında benzersizlik korunur. Bir Java programını çalıştırmak çok önemlidir.
uri nedir
Java ClassLoader üç prensibe dayanmaktadır: Delegasyon , Görünürlük , Ve benzersizlik .
ClassLoader Türleri
Java'da her ClassLoader'ın sınıf dosyalarını yüklediği önceden tanımlanmış bir konumu vardır. Java'da aşağıdaki ClassLoader türleri vardır:
Bootstrap Sınıfı Yükleyici: Rt.jar ve diğer çekirdek sınıflardan standart JDK sınıfı dosyalarını yükler. Tüm sınıf yükleyicilerin ebeveynidir. Herhangi bir ebeveyni yoktur. String.class.getClassLoader()'ı çağırdığımızda null değerini döndürür ve onu temel alan herhangi bir kod NullPointerException değerini atar. Aynı zamanda Primordial ClassLoader olarak da adlandırılır. Sınıf dosyalarını jre/lib/rt.jar'dan yükler. Örneğin Java.lang paket sınıfı.
Uzantılar Sınıfı Yükleyici: Sınıf yükleme isteğini ebeveynine devreder. Bir sınıfın yüklenmesi başarısız olursa, sınıfları jre/lib/ext dizininden veya başka bir dizinden java.ext.dirs olarak yükler. JVM'de sun.misc.Launcher$ExtClassLoader tarafından uygulanır.
Sistem Sınıfı Yükleyici: Uygulamaya özel sınıfları CLASSPATH ortam değişkeninden yükler. -cp veya sınıf yolu komut satırı seçenekleri kullanılarak program çağrılırken ayarlanabilir. Extension ClassLoader'ın bir çocuğudur. sun.misc.Launcher$AppClassLoader sınıfı tarafından uygulanır. Tüm Java ClassLoader, Java.lang.ClassLoader'ı uygular.
ClassLoader Java'da nasıl çalışır?
JVM bir sınıf için istekte bulunduğunda, sınıfın tam olarak sınıflandırılmış adını ileterek java.lang.ClassLoader sınıfının bir loadClass() yöntemini çağırır. loadClass() yöntemi, sınıfın önceden yüklenip yüklenmediğini kontrol etmek için findLoadedClass() yöntemini çağırır. Sınıfın birden çok kez yüklenmesinden kaçınmak gerekir.
Sınıf zaten yüklüyse, sınıfı yüklemesi için isteği üst ClassLoader'a devreder. ClassLoader sınıfı bulamıyorsa, dosya sistemindeki sınıfları aramak için findClass() yöntemini çağırır. Aşağıdaki şema ClassLoader'ın Java'da sınıfı yetkilendirmeyi kullanarak nasıl yüklediğini gösterir.
Uygulamaya özel bir Demo.class sınıfımız olduğunu varsayalım. Bu sınıf dosyalarının yüklenmesine yönelik istek, Application ClassLoader'a aktarılır. Ana Extension ClassLoader'a yetki verir. Ayrıca Bootstrap ClassLoader'a yetki verir. Bootstrap o sınıfı rt.jar'da arar ve o sınıf orada olmadığından. Şimdi jre/lib/ext dizinini arayan ve bu sınıfı orada bulmaya çalışan Extension ClassLoader'a aktarım isteğinde bulunun. Sınıf orada bulunursa Extension ClassLoader o sınıfı yükler. ClassLoader uygulaması bu sınıfı asla yüklemez. ClassLoader uzantısı bunu yüklemediğinde, ClaasLoader Uygulaması bunu Java'daki CLASSPATH'den yükler.
Görünürlük ilkesi, alt ClassLoader'ın üst ClassLoader tarafından yüklenen sınıfı görebildiğini belirtir ancak bunun tersi doğru değildir. Bu, Uygulama ClassLoader'ın Demo.class'ı yüklemesi durumunda, Extension ClassLoader'ı kullanarak Demo.class'ı açıkça yüklemeye çalışmanın Java.lang.ClassNotFoundException'ı oluşturduğu anlamına gelir.
Benzersizlik ilkesine göre ebeveyn tarafından yüklenen bir sınıfın Child ClassLoader tarafından tekrar yüklenmemesi gerekir. Böylece, delegasyon ve benzersizlik ilkelerini ihlal eden ve sınıfı kendi kendine yükleyen sınıf yükleyicisi yazmak mümkündür.
Kısacası, sınıf yükleyici aşağıdaki kuralı takip eder:
- Sınıfın zaten yüklü olup olmadığını kontrol eder.
- Sınıf yüklenmemişse, ana sınıf yükleyicisinden sınıfı yüklemesini isteyin.
- Ana sınıf yükleyicisi sınıfı yükleyemezse, onu bu sınıf yükleyicisine yüklemeyi deneyin.
Aşağıdaki Örneği göz önünde bulundurun:
public class Demo { public static void main(String args[]) { System.out.println('How are you?'); } }
Aşağıdaki komutu kullanarak yukarıdaki kodu derleyin ve çalıştırın:
javac Demo.java java -verbose:class Demo
-ayrıntılı:sınıf: JVM tarafından yüklenen sınıflarla ilgili bilgileri görüntülemek için kullanılır. Sınıfları dinamik olarak yüklemek için sınıf yükleyiciyi kullanırken kullanışlıdır. Aşağıdaki şekil çıktıyı göstermektedir.
İlk önce uygulama sınıfının (Demo) gerektirdiği çalışma zamanı sınıflarının yüklendiğini görebiliriz.
Sınıflar yüklendiğinde
Yalnızca iki durum vardır:
- Yeni bayt kodu yürütüldüğünde.
- Bayt kodu bir sınıfa statik bir referans yaptığında. Örneğin, Sistem çıkışı .
Statik ve Dinamik Sınıf Yüklemesi
Sınıflar statik olarak 'yeni' operatörüyle yüklenir. Dinamik sınıf yükleme, çalışma zamanında Class.forName() yöntemini kullanarak bir sınıf yükleyicinin işlevlerini çağırır.
loadClass() ve Class.forName() arasındaki fark
loadClass() yöntemi yalnızca sınıfı yükler ancak nesneyi başlatmaz. While Class.forName() yöntemi, nesneyi yükledikten sonra başlatır. Örneğin, JDBC sürücüsünü yüklemek için ClassLoader.loadClass() kullanıyorsanız, sınıf yükleyici JDBC sürücüsünün yüklenmesine izin vermez.
Java.lang.Class.forName() yöntemi, verilen dize adına sahip sınıf veya arayüzlerle birleştirilmiş Sınıf Nesnesini döndürür. Sınıf bulunamazsa ClassNotFoundException oluşturur.
Örnek
Bu örnekte Java.lang.String sınıfı yüklenmiştir. Sınıf adını, paket adını ve String sınıfının mevcut tüm yöntemlerinin adlarını yazdırır. Aşağıdaki örnekte Class.forName() kullanıyoruz.
Sınıf: Herhangi bir türden olabilen bir Class nesnesini temsil eder (? joker karakterdir). Class türü bir sınıf hakkında meta-bilgi içerir. Örneğin String.class'ın türü Class'tır. Modellenen sınıf bilinmiyorsa Class'ı kullanın.
getDeclaredMethod(): Genel, korumalı, varsayılan (paket) erişim ve özel yöntemler dahil, ancak devralınan yöntemler hariç olmak üzere, bu Class nesnesi tarafından temsil edilen sınıf veya arabirimin tüm bildirilen yöntemlerini yansıtan Method nesnelerini içeren bir dizi döndürür.
getName(): Bu Method nesnesi tarafından temsil edilen yöntem adını bir String olarak döndürür.
import java.lang.reflect.Method; public class ClassForNameExample { public static void main(String[] args) { try { Class cls = Class.forName('java.lang.String'); System.out.println('Class Name: ' + cls.getName()); System.out.println('Package Name: ' + cls.getPackage()); Method[] methods = cls.getDeclaredMethods(); System.out.println('-----Methods of String class -------------'); for (Method method : methods) { System.out.println(method.getName()); } } catch (ClassNotFoundException e) { e.printStackTrace(); } } }
Çıktı
Class Name: java.lang.String Package Name: package java.lang -----Methods of String class ------------- value coder equals length toString hashCode getChars ------ ------ ------ intern isLatin1 checkOffset checkBoundsOffCount checkBoundsBeginEnd access0 access0