Perbedaan Java dengan bahasa lainnya adalah Java berjalan di Java Virtual Machine (JVM). Ini berarti bahwa kode yang dikompilasi disimpan dalam format yang tidak bergantung pada platform, bukan dalam format yang berjalan pada mesin tertentu. Format ini memiliki banyak perbedaan penting dari format kode tradisional yang dapat dieksekusi. Secara khusus, tidak seperti program C atau C++, program Java bukanlah file eksekusi independen, namun terdiri dari banyak file kelas terpisah, masing-masing file kelas terkait dengan kelas Java. Selain itu, file kelas ini tidak langsung dimuat ke dalam memori, tetapi dimuat saat program membutuhkannya. Pemuat kelas adalah alat yang digunakan di mesin virtual Java untuk memuat kelas ke dalam memori. Selain itu, pemuat kelas Java juga diimplementasikan di Java. Dengan cara ini Anda dapat dengan mudah membuat pemuat kelas Anda sendiri tanpa harus memiliki pemahaman mendalam tentang mesin virtual Java.
Mengapa membuat pemuat kelas?
Sekarang mesin virtual Java sudah memiliki pemuat kelas, apakah kita perlu membuat yang lain sendiri? Pemuat kelas default hanya mengetahui cara memuat kelas dari sistem lokal. Ketika program Anda dikompilasi sepenuhnya secara asli, pemuat kelas default umumnya berfungsi dengan baik. Namun salah satu hal yang paling menarik tentang Java adalah betapa mudahnya memuat kelas dari jaringan, bukan hanya secara lokal.
Misalnya, browser dapat memuat kelas melalui pemuat kelas khusus. Ada juga banyak cara untuk memuat kelas. Salah satu hal paling menarik tentang Java adalah Anda dapat menyesuaikannya selain dari lokal atau jaringan:
* Secara otomatis memverifikasi tanda tangan digital sebelum menjalankan kode yang tidak tepercaya
* Dekripsi kode berdasarkan kata sandi yang diberikan oleh pengguna
* Buat kelas secara dinamis sesuai kebutuhan pengguna. Apa pun yang Anda pedulikan dapat dengan mudah diintegrasikan ke dalam aplikasi Anda dalam bentuk bytecode. Contoh pemuat kelas khusus jika Anda telah menggunakan appletviewer JDK (Java Software Development Kit) (browser aplikasi kecil) atau lainnya.
Untuk browser tertanam Java, Anda sudah menggunakan pemuat kelas khusus. Ketika Sun pertama kali merilis bahasa Java, salah satu hal yang paling menarik adalah menyaksikan bagaimana Java mengeksekusi kode yang diunduh dari situs web jarak jauh. Jalankan dari situs jarak jauh melalui HTTP
Bytecode yang dikirimkan oleh koneksi P terlihat agak aneh. Ini berfungsi karena Java memiliki kemampuan untuk menginstal pemuat kelas khusus. Browser applet berisi pemuat kelas. Pemuat kelas ini tidak menemukan kelas Java secara lokal. Sebaliknya, ia mengakses server jarak jauh, memuat file bytecode asli melalui HTTP, dan kemudian mengubahnya menjadi kelas Java di mesin virtual Java. Tentu saja pemuat kelas melakukan banyak hal lain: mereka memblokir kelas Java yang tidak aman dan menjaga applet yang berbeda pada halaman berbeda agar tidak saling mengganggu. Echidna, sebuah paket yang ditulis oleh Luke Gorrie, adalah paket perangkat lunak Java terbuka yang memungkinkan beberapa aplikasi Java dijalankan dengan aman di mesin virtual Java. Ini mencegah interferensi antar aplikasi dengan menggunakan pemuat kelas khusus untuk memberikan setiap aplikasi salinan file kelas.
pemuat kelas Java:
Ada tiga pemuat kelas secara default di Java: pemuat kelas bootstrap, pemuat kelas ekstensi, dan pemuat kelas sistem (juga disebut pemuat kelas aplikasi)
Pemuat kelas adalah salah satu fitur Java yang paling canggih. Namun pengembang sering kali lupa memuat komponen secara kelas. Pemuat kelas adalah kelas yang bertanggung jawab untuk menemukan dan memuat file kelas saat runtime. Java mengizinkan penggunaan pemuat kelas yang berbeda, bahkan pemuat kelas khusus.
Program Java berisi banyak file kelas, masing-masing berhubungan dengan satu kelas Java, tidak seperti program C statis, file kelas ini dimuat ke dalam memori satu kali dan perlu dimuat kapan saja. Inilah yang membuat class loader berbeda. Ia memperoleh bytecode platform-independen dari file sumber (biasanya file .class atau .jar) dan kemudian memuatnya ke dalam ruang memori JVM sehingga dapat diinterpretasikan dan dieksekusi. Secara default, setiap kelas aplikasi dimuat oleh java.lang.ClassLoader. Karena dapat diwariskan, fungsinya dapat ditingkatkan secara bebas.
Pemuat kelas khusus
import java.io.*;
impor java.net.*;
import java.util.*;
import java.lang.reflect.Method;
kelas publik CustomClassLoader memperluas URLClassLoader {
masukan FileInputStream pribadi = null; //Aliran masukan file
private ByteArrayOutputStream keluar = null; //aliran keluaran array byte
private String[] url = null; //jalur pemuatan file kelas
byte pribadi[] data = null; //bytecode file kelas
private String extensionalName = ""; //Ekstensi file kelas
public CustomClassLoader(URL[] urls) memunculkan Pengecualian{
super(url);
this.url = String baru[urls.panjang];
for (int i = 0; i < urls.length; i++) {
this.url[i] = url[i].toURI().toString();
}
}
/*
* Parsing URL
*/
kekosongan pribadi setFilePath() {
for (int i = 0; i < this.url.length; i++) {
if (ini.url[i].substring(0,4).toLowerCase().equals("file") == true) {
ini.url[i] = ini.url[i].substring(5);
}
}
}
/*
* Dapatkan bytecode file dengan nama kelas yang ditentukan (nama paket + nama kelas)
* @nama nama String
* @kembalikan byte[]
*/
byte pribadi[] getFileData(Nama string) {
mencoba {
ini.setFilePath();
for (String url : this.url) {
String nama file = url + nama.ganti('.', '/').concat(".") +
ini.getExtensionalName();
input = FileInputStream baru (File baru (Nama file));
jika (masukan != nol) {
merusak;
}
}
keluar = new ByteArrayOutputStream();
data = byte baru[1024];
int len = -1;
while ((len = masukan.baca(data)) != -1) {
keluar.tulis(data, 0, len);
}
data = keluar.toByteArray();
} tangkapan (Pengecualian e) {
e.printStackTrace();
} Akhirnya {
mencoba {
jika (masukan != nol)
masukan.tutup();
jika (keluar!= nol)
keluar.tutup();
mengembalikan data;
} tangkapan (Pengecualian e) {
e.printStackTrace();
kembalikan nol;
}
}
}
/*
* Pencarian file kelas berdasarkan nama kelas yang ditentukan
* @param nama String
* @Kelas Kembali
*/
Kelas terlindung findClassByName(Nama string) {
mencoba {
byte[] data = ini.getFileData(nama);
jika (data == nol) {
kembalikan nol;
}
kembalikan this.defineClass(nama, data, 0, data.panjang);
} tangkapan (Pengecualian e) {
e.printStackTrace();
kembalikan nol;
}
}
/*
* Ganti metode loadClass()
* @param nama String
* @Kelas Kembali
*/
Kelas publik loadClass(Nama string) {
Kelas c = nol;
mencoba {
c = super.loadClass(nama);
} tangkapan (ClassNotFoundException e) {
e.printStackTrace();
} Akhirnya {
if (c == null) //Ketika metode default dari kelas induk tidak dimuat ke dalam kelas yang ditentukan, gunakan metode khusus untuk menemukannya
c = ini.findClassByName(nama);
kembali c;
}
}
String publik getExtensionalName() {
kembalikan nama ekstensional;
}
public void setExtensionalName(String extensionalName) {
this.extensionalName = extensionalName;
}
public static void main(String[] args) melempar Pengecualian {
URL[] url = new URL[] {new URL("file:e:/")}; //Tambahkan jalur ke kelas yang ingin Anda muat
//Bisa jaringan atau lokal
CustomClassLoader csl = CustomClassLoader baru(url);
csl.setExtensionalName("rs");
Kelas c1 = csl.loadClass("com.demo");
Obj objek = c1.newInstance();
Metode metode = c1.getMethod("printText", null);
metode.memanggil(obj, null);
}