Apa itu Java ClassLoader?

174

Dalam beberapa kalimat sederhana, apa itu Java ClassLoader, kapan digunakan dan mengapa?

OK, saya membaca artikel wiki. ClassLoader memuat kelas. BAIK. Jadi jika saya memasukkan file jar dan impor, ClassLoader melakukan pekerjaan.

Mengapa saya harus repot dengan ClassLoader ini? Saya tidak pernah menggunakannya dan tidak tahu itu ada.

Pertanyaannya adalah, mengapa kelas ClassLoader ada? Dan juga, bagaimana Anda menggunakannya dalam praktik? (Ada kasus, saya tahu.)

EugeneP
sumber
Anda akan mendapatkan hasil yang lebih baik jika mempersempit pertanyaan Anda, misalnya dengan menunjuk bagian tertentu yang tidak Anda pahami, bagaimana hal itu terkait dengan beberapa bahasa lain yang Anda kenal, dll.
JRL
75
Ini adalah pertanyaan yang sepenuhnya masuk akal, jika dilihat dari sudut pandang seseorang yang mencari beberapa kalimat sederhana untuk menjelaskan konsep tersebut
oxbow_lakes
Video ini mungkin menarik: Apakah Anda Benar-Benar Mendapatkan Loader Kelas?
asmaier

Jawaban:

231

Diambil dari tutorial yang bagus dari Sun:

Motivasi

Aplikasi yang ditulis dalam bahasa pemrograman yang dikompilasi secara statis, seperti C dan C ++, dikompilasi menjadi asli, instruksi khusus mesin dan disimpan sebagai file yang dapat dieksekusi. Proses menggabungkan kode ke dalam kode asli yang dapat dieksekusi disebut tautan - penggabungan kode yang dikompilasi secara terpisah dengan kode pustaka bersama untuk membuat aplikasi yang dapat dieksekusi. Ini berbeda dalam bahasa pemrograman yang dikompilasi secara dinamis seperti Java. Di Jawa, file .class yang dihasilkan oleh kompiler Java tetap apa adanya hingga dimuat ke Java Virtual Machine (JVM) - dengan kata lain, proses penautan dilakukan oleh JVM saat runtime. Kelas dimuat ke JVM berdasarkan 'sesuai kebutuhan'. Dan ketika kelas dimuat tergantung pada kelas lain, maka kelas itu dimuat juga.

Ketika aplikasi Java diluncurkan, kelas pertama yang dijalankan (atau titik masuk ke dalam aplikasi) adalah kelas dengan metode public static void yang disebut main (). Kelas ini biasanya memiliki referensi ke kelas lain, dan semua upaya untuk memuat kelas yang dirujuk dilakukan oleh pemuat kelas.

Untuk merasakan pemuatan kelas rekursif ini dan juga gagasan pemuatan kelas secara umum, pertimbangkan kelas sederhana berikut ini:

public class HelloApp {
   public static void main(String argv[]) {
      System.out.println("Aloha! Hello and Bye");
   }
}

Jika Anda menjalankan kelas ini menentukan opsi -verbose: class-line perintah, sehingga mencetak kelas apa yang sedang dimuat, Anda akan mendapatkan output yang terlihat seperti berikut. Perhatikan bahwa ini hanya sebagian output karena daftar terlalu panjang untuk ditampilkan di sini.

prmpt>java -verbose:class HelloApp



[Opened C:\Program Files\Java\jre1.5.0\lib\rt.jar]
[Opened C:\Program Files\Java\jre1.5.0\lib\jsse.jar]
[Opened C:\Program Files\Java\jre1.5.0\lib\jce.jar]
[Opened C:\Program Files\Java\jre1.5.0\lib\charsets.jar]
[Loaded java.lang.Object from shared objects file]
[Loaded java.io.Serializable from shared objects file]
[Loaded java.lang.Comparable from shared objects file]
[Loaded java.lang.CharSequence from shared objects file]
[Loaded java.lang.String from shared objects file]
[Loaded java.lang.reflect.GenericDeclaration from shared objects file]
[Loaded java.lang.reflect.Type from shared objects file]
[Loaded java.lang.reflect.AnnotatedElement from shared objects file]
[Loaded java.lang.Class from shared objects file]
[Loaded java.lang.Cloneable from shared objects file]
[Loaded java.lang.ClassLoader from shared objects file]
[Loaded java.lang.System from shared objects file]
[Loaded java.lang.Throwable from shared objects file]
.
.
.
[Loaded java.security.BasicPermissionCollection from shared objects file]
[Loaded java.security.Principal from shared objects file]
[Loaded java.security.cert.Certificate from shared objects file]
[Loaded HelloApp from file:/C:/classes/]
Aloha! Hello and Bye
[Loaded java.lang.Shutdown from shared objects file]
[Loaded java.lang.Shutdown$Lock from shared objects file]

Seperti yang Anda lihat, kelas Java runtime yang diperlukan oleh kelas aplikasi (HelloApp) dimuat terlebih dahulu.

Loader Kelas di Platform Java 2

Bahasa pemrograman Java terus berkembang untuk membuat kehidupan para pengembang aplikasi lebih mudah setiap hari. Ini dilakukan dengan menyediakan API yang menyederhanakan hidup Anda dengan memungkinkan Anda berkonsentrasi pada logika bisnis daripada detail implementasi mekanisme fundamental. Hal ini terbukti dengan perubahan J2SE 1.5 menjadi J2SE 5.0 untuk mencerminkan kematangan platform Java.

Pada JDK 1.2, loader kelas bootstrap yang dibangun ke dalam JVM bertanggung jawab untuk memuat kelas-kelas Java runtime. Loader kelas ini hanya memuat kelas yang ditemukan di boot classpath, dan karena ini adalah kelas tepercaya, proses validasi tidak dilakukan seperti untuk kelas yang tidak terpercaya. Selain pemuat kelas bootstrap, JVM memiliki pemuat kelas ekstensi yang bertanggung jawab untuk memuat kelas dari API ekstensi standar, dan pemuat kelas sistem yang memuat kelas dari jalur kelas umum serta kelas aplikasi Anda.

Karena ada lebih dari satu pemuat kelas, mereka direpresentasikan dalam pohon yang akarnya adalah pemuat kelas bootstrap. Setiap pemuat kelas memiliki referensi ke pemuat kelas induknya. Ketika pemuat kelas diminta untuk memuat kelas, itu berkonsultasi dengan pemuat kelas induknya sebelum mencoba memuat item itu sendiri. Orang tua pada gilirannya berkonsultasi dengan orang tuanya, dan seterusnya. Jadi itu hanya setelah semua pemuat kelas leluhur tidak dapat menemukan kelas yang melibatkan pemuat kelas saat ini. Dengan kata lain, model delegasi digunakan.

Kelas java.lang.ClassLoader

Ini java.lang.ClassLoaderadalah kelas abstrak yang dapat disubklasifikasikan oleh aplikasi yang perlu memperluas cara di mana JVM memuat kelas secara dinamis. Konstruktor dalam java.lang.ClassLoader(dan subkelasnya) memungkinkan Anda untuk menentukan induk ketika Anda membuat instance kelas loader baru. Jika Anda tidak secara eksplisit menentukan induk, pemuat kelas sistem mesin virtual akan ditetapkan sebagai induk default. Dengan kata lain, kelas ClassLoader menggunakan model delegasi untuk mencari kelas dan sumber daya. Oleh karena itu, setiap instance dari ClassLoader memiliki loader kelas induk yang terkait, sehingga ketika diminta untuk menemukan kelas atau sumber daya, tugas didelegasikan ke loader kelas induknya sebelum berusaha menemukan kelas atau sumber daya itu sendiri. The loadClass()metode ClassLoader yang melakukan kegiatan sebagai berikut, agar, saat dipanggil untuk memuat kelas:

Jika kelas telah dimuat, itu mengembalikannya. Jika tidak, ia mendelegasikan pencarian kelas baru ke loader kelas induk. Jika pemuat kelas induk tidak menemukan kelas, loadClass()panggil metode findClass()untuk menemukan dan memuat kelas. The finalClass()Metode pencarian untuk kelas di kelas loader saat ini jika kelas tidak ditemukan oleh loader kelas induk.


Ada lebih banyak di artikel asli, yang juga menunjukkan kepada Anda bagaimana menerapkan pemuat kelas jaringan Anda sendiri, yang menjawab pertanyaan Anda tentang mengapa (dan bagaimana). Lihat juga dokumentasi API .

JRL
sumber
47

Sebagian besar pengembang Java tidak akan perlu secara eksplisit menggunakan pemuat kelas (kecuali untuk memuat sumber daya sehingga masih berfungsi ketika mereka dibundel dalam JAR), apalagi menulis sendiri.

ClassLoaders digunakan dalam sistem besar dan aplikasi server untuk melakukan hal-hal seperti:

  • Modularisasi sistem dan muat, bongkar, dan perbarui modul saat runtime
  • Gunakan versi berbeda dari pustaka API (misalnya parser XML) secara paralel
  • Mengisolasi aplikasi yang berbeda berjalan dalam JVM yang sama (memastikan mereka tidak saling mengganggu, misalnya melalui variabel statis)
Michael Borgwardt
sumber
29

Pertanyaannya adalah "Mengapa orang harus mengganggu kelas ClassLoader ini ada"?

Yah, sebagian besar sehingga Anda dapat memperbaiki masalah jika mereka salah :-).

Memang benar, selama Anda hanya menulis aplikasi, kompilasi ke JAR dan mungkin menyertakan beberapa JAR perpustakaan tambahan, Anda tidak perlu tahu tentang pemuat kelas, itu hanya akan berfungsi.

Namun, akan sangat membantu untuk mengetahui sedikit tentang pemuat kelas dan pemuatan kelas untuk lebih memahami apa yang terjadi di balik layar. Sebagai contoh, "initializers statis" akan berjalan ketika kelas dimuat, jadi untuk memahami kapan mereka akan berjalan, Anda perlu tahu bagaimana pemuat kelas memutuskan kapan harus memuatnya.

juga .. bagaimana Anda menggunakannya dalam praktek?

Untuk kasus sederhana, Anda tidak membutuhkannya. Namun, jika Anda perlu memuat kode secara dinamis saat runtime dengan kontrol eksplisit dari mana asalnya (misalnya memuat melalui jaringan, memuat plugin tidak tersedia pada waktu kompilasi, dll.), Anda mungkin perlu berbuat lebih banyak. Maka Anda dapat misalnya menulis loader kelas Anda sendiri. Lihat jawaban lain untuk tautan.

sleske
sumber
14

ClassLoaderdi Jawa adalah kelas yang digunakan untuk memuat file kelas di Jawa. Kode Java dikompilasi ke file kelas oleh javackompiler dan JVM mengeksekusi program Java, dengan mengeksekusi kode byte yang ditulis dalam file kelas.

ClassLoader bertanggung jawab untuk memuat file kelas dari sistem file, jaringan atau sumber lainnya. Ada tiga pemuat kelas default yang digunakan di Java, Bootstrap , Extension dan Sistem atau pemuat kelas Aplikasi .

ClassLoader


Cara kerja ClassLoader

## Interaksi ClassLoader dengan JVM masukkan deskripsi gambar di sini

More @: how-classloader-works-in-java.html

roottraveller
sumber
6

Class Loader adalah komponen fungsional JVM, yang memuat data kelas dari file '.class' atau dari jaringan ke dalam Metode Area di Heap.

Tampak seperti bagian integral dari JVM, tetapi sebagai pengguna java mengapa saya harus khawatir? Inilah alasannya:

Setiap pemuat kelas memiliki ruang nama sendiri dan kelas yang dipanggil oleh pemuat kelas tertentu masuk ke ruang nama itu.

Kelas yang dipanggil oleh dua loader kelas yang berbeda tidak akan memiliki visibilitas satu sama lain, menghasilkan keamanan yang ditingkatkan.

Mekanisme delegasi anak induk pemuat kelas memastikan bahwa kelas java api tidak akan pernah diretas oleh kode yang tidak sah.

Untuk detailnya lihat di sini

bitan
sumber
1

Loader kelas bersifat hierarkis. Kelas diperkenalkan ke JVM karena direferensikan dengan nama di kelas yang sudah berjalan di JVM.

Bagaimana kelas pertama dimuat?
Kelas pertama dimuat dengan bantuan static main()metode yang dideklarasikan di kelas Anda. Semua kelas selanjutnya dimuat oleh kelas, yang sudah dimuat dan berjalan.

Pemuat kelas menciptakan namespace. Semua JVM menyertakan setidaknya satu loader kelas yang tertanam di dalam JVM yang disebut loader kelas primordial (atau bootstrap) . Itu adalah satu hal, dan kita akan melihat loader kelas non-primordial. JVM memiliki kait di dalamnya untuk memungkinkan pemuat kelas yang ditentukan pengguna digunakan sebagai pengganti pemuat kelas primordial. Berikut ini adalah pemuat kelas yang dibuat oleh JVM.

Bootstrap (primordial) Loader kelas ini tidak dapat dimuat ulang. Memuat kelas internal JDK, paket java. * (Biasanya memuat rt.jar dan i18n.jar). Ekstensi Kelas ini tidak dapat dimuat ulang. Memuat file jar dari direktori ekstensi JDK (biasanya lib / ext dari JRE). Sistem Pemuat kelas ini tidak dapat dimuat ulang. Memuat kelas dari jalur kelas sistem.

http://www.sbalasani.com/2015/01/java-class-loaders.html

Srinivas Balasani
sumber
1

Ketika Anda bertanya mengapa kelas ClassLoader ada, alasannya cukup sederhana - kelaslah yang bertanggung jawab untuk menemukan dan memuat file kelas saat dijalankan .

Mari kita jelaskan.

Dalam JVM, setiap Kelas dimuat oleh beberapa instance dari java.lang.ClassLoader. Setiap kali JVM baru dimulai oleh Anda java <classname>perintah peluncuran program Java biasa , langkah pertama adalah memuat semua kelas kunci dalam memori yang diperlukan untuk bekerja dengan baik seperti java.lang.Objectdan kelas runtime lainnya ( rt.jar).

Sekarang, sebenarnya ada 3 bagian untuk ClassLoader:

  • The BootstrapClassLoaderbertanggung jawab untuk membuat kelas-kelas ini tersedia yaitu memuat kelas-kelas dalam memori.

  • Tugas selanjutnya adalah memuat pustaka / JAR eksternal ke dalam memori agar aplikasi berfungsi dengan baik. The ExtClassLoaderbertanggung jawab untuk tugas ini. Pemuat kelas ini bertanggung jawab untuk memuat semua file .jar yang disebutkan di jalur java.ext.dirs.

  • Loader kelas penting ketiga dan utama adalah AppClassLoader. Pemuat kelas aplikasi bertanggung jawab untuk memuat file kelas yang disebutkan dalam properti sistem java.class.path.

Penting juga untuk dicatat bahwa implementasi ClassLoader default dapat diganti memungkinkan Anda untuk menyesuaikan JVM dengan cara yang berguna dan menarik, memungkinkan Anda untuk sepenuhnya mendefinisikan ulang bagaimana file kelas dibawa ke dalam sistem.

masukkan deskripsi gambar di sini

Lihat itu untuk mempelajari lebih lanjut tentang Java Class Loader .

Johnny
sumber