🔬 فحص الأنواع

فلنتخيل أنك دخلت إلى مقابلة عمل لوظيفة مبرمج في جافا وواجهك هذا السؤال:

في هذا الكود، ماهو نوع المتحولات o و n و i ؟

Object  o = new Integer(4);
Number  n = new Integer(4);
Integer i = new Integer(4);

حقيقةً السؤال مضلل نوعاً ما، فلا جوابَ مباشرْ. في جاڤا كما في معظم لغات البرمجة التي تدعم البرمجة الغرضية هناك تعدد الأشكال (Polymorphism) حيث يمكن لمتحول أن يأخذ عدة أشكال.

نظام الأنواع Type System

تعتبر جافا لغةً ذات نظام أنواع قوي (Strongly Typed Language)، أي إذا مر الكود مرحلة الترجمة (Compilation)، فإن البرنامج سيعمل بدون مفاجآت عموماً.

⚠️ لايوجد إجماع على تعريف رسمي (Formal Definition) لقوة نظام الأنواع

عندما نقوم بإسناد قيمة تابع ما لمتحول، يتم التحقق من صحة هذه العملية عبر نظام جافا للتحقق من الأنواع (Java Type Checker).

لهذا لايمكنك أن تكتب:

Integer age = scanner.nextLine();

لأن المتحول age له نوع Integer ومتحقق الأنواع في جافا يرى أنك تحاول إسناده scanner.nextLine التي ترجع قيمة نصية String، وبالتالي لايسمح لك حتّى بترجمة الكود.

💡 في جافاسكربت مثلاً هكذا خطأ لا يُكتشف إلا عند تشغيل الكود

بينما هذا الكود يعمل بدون مشاكل لأننا عرفنا عن المتحول age من نوع Object.

Object age = scanner.nextLine();

💡 الكلاس Object هو أب لكل الكلاسات في جافا، أي أن جميع الكلاسات ترثه. وبالتالي مُتحقق الأنواع (Type Checker) لا يرى مشكلة في هذا.

قبل الخوض في الإجابة عن السؤال في بداية المنشور، يجب أن نبيّن أن للمتحولات نوعان:

  • نوع ستاتيكي (Static Type) : النوع الذي تم التعريف عنه في الكود قبل اسم المتحول. (ثابت لايتغير)
  • نوع ديناميكي (Dynamic Type) : نوع الكائن (Object) الذي تم إسناده إليهم. (يمكن أن يتغير)

فلنأخذ هذا الكود كمثال:

Object o = new Integer(4);
       o = new String("I am a string now");

نرى أن المتحول o له النوع الستاتيكي Object الذي لا يمكن أن يتغير. ولكن في السطر الأول المتحول له النوع الديناميكي Integer والقيمة العددية 4، أما في السطر الثاني فيتغير نوعه إلى String وتصبح قيمته I am a string now.

🤔 كيف سمحت لنا جافا باسناد عدد ونص لذات المتحول؟

فلنجرّب

من المعلوم أن جافا لاتسمح بتخزين متحولات من أكثر من نوع في نفس المصفوفة، ولكن يمكننا التحايل على جافا وجعلها تسمح بذلك عبر تعريف مصفوفة من نوع Object (نوع ستاتيكي). ولكن نملأ عناصرها بنصوص وأرقام.

بعدها نمر على عناصر المصفوفة ونتحقق من النوع الديناميكي، في حال كان رقماً صحيحاً Integer أو نصاً String، نطبع ذلك مع قيمة العنصر.

public class TypeChecking {

    public static void main(String[] args) {
        Object array[] = new Object[4];

        array[0] = new String("Name 1");
        array[1] = new Integer(4);
        array[2] = new String("Name 2");
        array[3] = new Double(3.14);

        for (int i = 0; i < 4; i++) {
            if (array[i] instanceof String) {
                System.out.print("This is a string: ");
                System.out.println(array[i]);
            } else if (array[i] instanceof Integer) {
                System.out.print("This is an integer: ");
                System.out.println(array[i]);
            } else {
                System.out.println("Unknown dynamic type.");
            }
        }
    }
}

◀️ جرب الكود

💡 الكلمة المفتاحية (Keyword) instanceof تتحقق من أصل الكائن (كلاسه)

إذاً ما الجواب؟

حسب ماسبق يكون جواب السؤال في أول المنشور أن النوع الستاتيكي لكل من o و n وi هو Object و Number و Integer على الترتيب. النوع الديناميكي هو Integer للكل.