الفرق بين Java واللغات الأخرى هو أن Java تعمل على Java Virtual Machine (JVM). وهذا يعني أنه يتم حفظ التعليمات البرمجية المترجمة بتنسيق مستقل عن النظام الأساسي، بدلاً من التنسيق الذي يتم تشغيله على جهاز معين. يحتوي هذا التنسيق على العديد من الاختلافات المهمة عن تنسيق التعليمات البرمجية القابل للتنفيذ التقليدي. على وجه التحديد، على عكس برنامج C أو C++، فإن برنامج Java ليس ملفًا مستقلاً قابلاً للتنفيذ، ولكنه يتكون من العديد من ملفات الفئات المنفصلة، كل ملف فئة يتوافق مع فئة Java. بالإضافة إلى ذلك، لا يتم تحميل ملفات الفئات هذه إلى الذاكرة على الفور، ولكن يتم تحميلها عندما يحتاج البرنامج إليها. أداة تحميل الفئة هي أداة تستخدم في جهاز Java الظاهري لتحميل الفئات في الذاكرة. علاوة على ذلك، يتم تطبيق محمل فئة Java أيضًا في Java. بهذه الطريقة يمكنك بسهولة إنشاء أداة تحميل الفئة الخاصة بك دون الحاجة إلى فهم متعمق لجهاز Java الظاهري.
لماذا إنشاء محمل فئة؟
الآن بعد أن أصبح لدى جهاز Java الظاهري مُحمل فئة بالفعل، هل نحتاج إلى إنشاء برامج أخرى بأنفسنا؟ يعرف مُحمل الفئة الافتراضي فقط كيفية تحميل الفئات من النظام المحلي. عندما يتم تجميع برنامجك بالكامل محليًا، فإن مُحمل الفئة الافتراضي يعمل بشكل جيد بشكل عام. لكن أحد الأشياء الأكثر إثارة في Java هو مدى سهولة تحميل الفئات من الشبكة بدلاً من تحميلها محليًا فقط.
على سبيل المثال، يمكن للمتصفح تحميل الفئات من خلال أداة تحميل فئة مخصصة. هناك أيضًا العديد من الطرق لتحميل الفصول الدراسية. أحد أكثر الأشياء إثارة في Java هو أنه يمكنك تخصيصها إلى جانب ذلك ببساطة من الشبكة المحلية أو الشبكة:
* التحقق تلقائيًا من التوقيعات الرقمية قبل تنفيذ تعليمات برمجية غير موثوقة
* فك تشفير الكود بناءً على كلمة المرور المقدمة من المستخدم
* إنشاء فئات ديناميكيًا وفقًا لاحتياجات المستخدم يمكن دمجه بسهولة في التطبيق الخاص بك في شكل رمز ثانوي. أمثلة على أدوات تحميل الفئات المخصصة إذا كنت قد استخدمت برنامج JDK (Java Software Development Kit) (متصفح التطبيقات الصغيرة) أو غيره.
بالنسبة لمتصفحات Java المضمنة، فإنك تستخدم بالفعل أداة تحميل فئة مخصصة. عندما أصدرت شركة Sun لغة Java لأول مرة، كان أحد أكثر الأشياء إثارة هو مشاهدة كيفية تنفيذ Java للتعليمات البرمجية التي تم تنزيلها من موقع ويب بعيد. التنفيذ من موقع بعيد عبر HTTP
يبدو رمز البايت الذي يرسله اتصال P غريبًا بعض الشيء. يعمل هذا لأن Java لديها القدرة على تثبيت أدوات تحميل فئة مخصصة. يحتوي متصفح التطبيق الصغير على مُحمل فئة. لا يعثر مُحمل الفئة هذا على فئات Java محليًا، وبدلاً من ذلك، فإنه يصل إلى الخادم البعيد، ويقوم بتحميل ملف الرمز الثانوي الأصلي من خلال HTTP، ثم يقوم بتحويله إلى فئة Java في جهاز Java الظاهري. بالطبع تقوم أدوات تحميل الفئات بالكثير من الأشياء الأخرى: فهي تحظر فئات Java غير الآمنة وتمنع التطبيقات الصغيرة الموجودة على صفحات مختلفة من التدخل مع بعضها البعض. Echidna، وهي حزمة كتبها Luke Gorrie، هي حزمة برامج Java مفتوحة تسمح بتشغيل تطبيقات Java المتعددة بأمان في جهاز Java الظاهري. يمنع التداخل بين التطبيقات باستخدام مُحمل فئة مخصص لإعطاء كل تطبيق نسخة من ملف الفئة.
محمل فئة جافا:
توجد ثلاث أدوات تحميل للفئات بشكل افتراضي في Java: مُحمل فئة التمهيد، ومُحمل فئة الامتداد، ومُحمل فئة النظام (يُسمى أيضًا مُحمل فئة التطبيق)
تعد أدوات تحميل الفئة إحدى أقوى ميزات Java. لكن المطورين غالبًا ما ينسون تحميل المكونات. محمل الفئة هو فئة مسؤولة عن البحث عن ملفات الفئة وتحميلها في وقت التشغيل. تسمح Java باستخدام مُحملات فئات مختلفة، حتى مُحملات الفئات المخصصة.
تحتوي برامج Java على العديد من ملفات الفئات، كل منها يتوافق مع فئة Java واحدة. على عكس برامج C الثابتة، يتم تحميل ملفات الفئات هذه في الذاكرة مرة واحدة ويجب تحميلها في أي وقت. هذا ما يجعل محمل الفصل مختلفًا. فهو يحصل على رموز ثانوية مستقلة عن النظام الأساسي من الملفات المصدر (عادةً ملفات .class أو .jar) ثم يقوم بتحميلها في مساحة ذاكرة JVM حتى يمكن تفسيرها وتنفيذها. افتراضيًا، يتم تحميل كل فئة من التطبيق بواسطة java.lang.ClassLoader. ولأنه يمكن توريثه، يمكن تحسين وظائفه بحرية.
محمل فئة مخصصة
استيراد java.io.*;
استيراد java.net.*;
import java.util.*;
import java.lang.reflect.Method;
الطبقة العامة CustomClassLoader تمتد URLClassLoader {
Private FileInputStream input = null; // دفق إدخال الملف
Private ByteArrayOutputStream out = null; // دفق إخراج صفيف البايت
Private String[] url = null; // مسار تحميل ملف الفئة
بايت خاص[] data = null; // ملف فئة bytecode
اسم السلسلة الخاص = ""; // ملحق ملف الفئة
CustomClassLoader العام (URL[] urls) يطرح استثناءً {
super(url);
this.url = new String[urls.length];
لـ (int i = 0; i < urls.length; i++) {
this.url[i] = urls[i].toURI().toString();
}
}
/*
* تحليل URL
*/
مجموعة باطلة خاصة () {
for (int i = 0; i < this.url.length; i++) {
إذا (this.url[i].substring(0,4).toLowerCase().equals("file") == true) {
this.url[i] = this.url[i].substring(5);
}
}
}
/*
* الحصول على الرمز الثانوي للملف باسم الفئة المحدد (اسم الحزمة + اسم الفئة)
* @اسم سلسلة الاسم
* @إرجاع البايت[]
*/
البايت الخاص[] getFileData(اسم السلسلة) {
يحاول {
this.setFilePath();
لـ (سلسلة URL: this.url) {
String fileName = url + name.replace('.', '/').concat(".") +
this.getExtensionalName();
input = new FileInputStream(new File(fileName));
إذا (الإدخال!= فارغة) {
استراحة؛
}
}
out = new ByteArrayOutputStream();
البيانات = بايت جديد[1024]؛
إنت لين = -1;
بينما ((لين = input.read(data)) != -1) {
out.write(data, 0, len);
}
data = out.toByteArray();
} قبض (الاستثناء ه) {
printStackTrace();
} أخيراً {
يحاول {
إذا (الإدخال! = فارغ)
input. Close();
إذا (خارج! = فارغة)
out.Close();
إرجاع البيانات؛
} قبض (الاستثناء ه) {
printStackTrace();
عودة فارغة؛
}
}
}
/*
* البحث في ملفات الفصل بناءً على اسم الفصل المحدد
* سلسلة اسمparam
* @ فئة العودة
*/
الفئة المحمية findClassByName(اسم السلسلة) {
يحاول {
byte[] data = this.getFileData(name);
إذا (البيانات == فارغة) {
عودة فارغة؛
}
إرجاع this.defineClass(name, data, 0, data. length);
} قبض (الاستثناء ه) {
printStackTrace();
عودة فارغة؛
}
}
/*
* تجاوز طريقة LoadClass()
* سلسلة اسمparam
* @ فئة العودة
*/
تحميل الفئة العامة (اسم السلسلة) {
الفئة ج = فارغة؛
يحاول {
ج = super.loadClass(name);
} التقاط (ClassNotFoundException e) {
printStackTrace();
} أخيراً {
if (c == null) // عندما لا يتم تحميل الطريقة الافتراضية للفئة الأصلية في الفئة المحددة، استخدم طريقة مخصصة للعثور عليها
c = this.findClassByName(name);
العودة ج؛
}
}
سلسلة عامة getExtensionalName() {
إرجاع الاسم الامتداد؛
}
مجموعة الفراغ العام ExtensionalName (سلسلة تمديد الاسم) {
this.extensionalName = ExtensionalName;
}
public static void main(String[] args) يطرح الاستثناء {
URL[] url = new URL[] {new URL("file:e:/")}; // أضف المسار إلى الفصل الذي تريد تحميله
// يمكن أن تكون شبكة أو محلية
CustomClassLoader csl = new CustomClassLoader(url);
csl.setExtensionalName("rs");
Class c1 = csl.loadClass("com.demo");
Object obj = c1.newInstance();
طريقة الطريقة = c1.getMethod("printText", null);
way.invoc(obj, null);
}