0Pricing
Java Academy · درس

استدعاء الأساليب والوصول إلى الحقول

استدعِ الأساليب الخاصة واضبط الحقول غير القابلة للوصول باستخدام Method.invoke وField.set مع setAccessible

استدعاء الأساليب والوصول إلى الحقول درس مجاني في Java Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Java Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Java Academy 4 دروس في المجموع.

setAccessible: تجاوز مستوى الوصول

استدعِ field.setAccessible(true) أو method.setAccessible(true) لتجاوز نظام التحكم في الوصول في Java. وهذا مطلوب للوصول إلى الأعضاء الخاصة. كما يتطلب صلاحية وصول مناسبة إلى الوحدة في Java 9 وما بعدها.

Field f = User.class.getDeclaredField("name");
f.setAccessible(true);
User u = new User("Alice", 30);
System.out.println(f.get(u));  // "Alice"
f.set(u, "Bob");               // mutate the private field
System.out.println(u.getName()); // "Bob"

قراءة قيم الحقول

استخدم field.get(instance) لقراءة قيمة أي حقل، مع تغليف القيم البدائية. وبالنسبة إلى الحقول الساكنة، مرّر null بوصفه الكائن.

Field f = MyClass.class.getDeclaredField("count");
f.setAccessible(true);
int count = (int) f.get(null); // static field → null instance

تعيين قيم الحقول

استخدم field.set(instance, value) لكتابة قيمة في حقل. يجب أن يطابق نوع القيمة نوع الحقل، أو أن تكون قابلة لإزالة التغليف تلقائيًا. ويُعد تعيين حقل final عبر الانعكاس سلوكًا غير محدد في JVM الحديثة.

Field nameField = User.class.getDeclaredField("name");
nameField.setAccessible(true);
nameField.set(user, "Charlie");

استدعاء الأساليب عبر الانعكاس

استرجع كائن Method، ثم استدعِ setAccessible(true)، وبعد ذلك استدعِ الأسلوب باستخدام method.invoke(instance, args...). وتكون القيمة المعادة من النوع Object.

Method greet = User.class.getDeclaredMethod("greet", String.class);
greet.setAccessible(true);
String result = (String) greet.invoke(user, "World");
System.out.println(result);

معالجة InvocationTargetException

إذا ألقى الأسلوب المستدعى استثناءً، فسيغلفه الانعكاس داخل InvocationTargetException. أزل التغليف باستخدام getCause().

try {
    method.invoke(obj, args);
} catch (InvocationTargetException e) {
    Throwable cause = e.getCause();
    System.err.println("Method threw: " + cause.getMessage());
} catch (IllegalAccessException | NoSuchMethodException e) {
    System.err.println("Reflection error: " + e.getMessage());
}

استدعاء الأساليب الساكنة

مرّر null بوصفه وسيطة الكائن عند استدعاء الأساليب الساكنة.

Method parseInt = Integer.class.getDeclaredMethod("parseInt", String.class);
int value = (int) parseInt.invoke(null, "42"); // null = static
System.out.println(value); // 42

إنشاء كائنات عبر منشئ

احصل على Constructor، واستدعِ setAccessible(true) للمنشئات الخاصة، ثم استدعِ newInstance(args...).

Constructor<User> ctor = User.class.getDeclaredConstructor(String.class, int.class);
ctor.setAccessible(true);
User u = ctor.newInstance("Diana", 28);
System.out.println(u);

الانعكاس في أطر العمل: Spring DI

يستخدم Spring الانعكاس لإنشاء beans وحقن التبعيات. فهو يستدعي المنشئات الخاصة ويعيّن قيم الحقول الخاصة لربط سياق التطبيق.

الوصول إلى الوحدات في Java 9 وما بعدها

تقيّد الوحدات في Java 9 وما بعدها setAccessible افتراضيًا. إذا كان الصنف موجودًا في وحدة مُسمّاة، فقد تحتاج إلى فتح الحزمة باستخدام: --add-opens java.base/java.lang=ALL-UNNAMED.

// JVM flag to open a package for reflection:
// --add-opens java.base/java.lang=ALL-UNNAMED

MethodHandles كبديل أسرع

يوفّر MethodHandles.lookup().findVirtual() استدعاءً انعكاسيًا للأساليب بأداء قريب من الاستدعاء المباشر بعد تحسين JIT. ويُفضّل استخدامه في كود المكتبات الحسّاس للأداء.

MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(User.class, MethodHandles.lookup());
MethodHandle handle = lookup.findVirtual(User.class, "getName", MethodType.methodType(String.class));
String name = (String) handle.invoke(user);

أفضل ممارسات الانعكاس

خزّن كائنات Field/Method مؤقتًا — ولا تسترجعها أبدًا داخل الحلقات عالية التكرار. غلّف الانعكاس داخل أصناف الخدمات. ضع في اعتبارك استخدام MethodHandles لتحسين الأداء. وفضّل الواجهات على الانعكاس متى أمكن.

تحقق سريع

عندما يلقي أسلوب مستدعًى بالانعكاس استثناءً، فما الاستثناء الذي يغلف السبب؟

مراجعة

استخدم setAccessible(true) للوصول إلى الأعضاء الخاصة. واستدعِ الأساليب عبر method.invoke(). أزل تغليف InvocationTargetException. خزّن الكائنات الانعكاسية مؤقتًا. وفضّل MethodHandles في المسارات عالية الاستخدام.

الأسئلة الشائعة

هل درس «استدعاء الأساليب والوصول إلى الحقول» مجاني؟

نعم — نص درس «استدعاء الأساليب والوصول إلى الحقول» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Java Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Java Academy 4 دروس في المجموع.

ماذا ستتعلم في «استدعاء الأساليب والوصول إلى الحقول»؟

استدعِ الأساليب الخاصة واضبط الحقول غير القابلة للوصول باستخدام Method.invoke وField.set مع setAccessible تتمرن على Java Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Java Academy؟

لا تُشترط خبرة سابقة. Java Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.

كم من الوقت يستغرق درس «استدعاء الأساليب والوصول إلى الحقول»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Java Academy هذا؟

نعم. كل درس في Java Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. فحص الفئات باستخدام Reflection
  2. استدعاء الأساليب والوصول إلى الحقول
  3. الوكلاء الديناميكيون باستخدام InvocationHandler
  4. أداء Reflection والبدائل
← العودة إلى Java Academy