سؤال

النظر في المقتطف التالي:

    int i = 99999999;
    byte b = 99;
    short s = 9999;
    Integer ii = Integer.valueOf(9); // should be within cache

    System.out.println(new Integer(i) == i); // "true"
    System.out.println(new Integer(b) == b); // "true"
    System.out.println(new Integer(s) == s); // "true"
    System.out.println(new Integer(ii) == ii); // "false"

من الواضح لماذا سيفعل السطر الأخير دائماً مطبوعات "false": كانوا يستخدمون == مقارنة الهوية المرجعية ، و new إرادة الكائن مطلقا يكون == إلى كائن موجود بالفعل.

السؤال يدور حول الأسطر الثلاثة الأولى: هل تلك المقارنات مضمون أن تكون على البدائية int, ، مع ال Integer تلقائيًا غير محصور؟ هل هناك حالات يكون فيها البدائي محصورًا تلقائيًا بدلاً من ذلك ، ويتم إجراء مقارنات الهوية المرجعية؟ (أي شيء سيكون بعد ذلك false!)

هل كانت مفيدة؟

المحلول

نعم. JLS §5.6.2 يحدد قواعد الترويج الرقمي الثنائي. في جزء:

عندما يطبق المشغل الترويج الرقمي الثنائي على زوج من المعاملات ، يجب أن يشير كل منها :

إذا كان أي من المعاملات من نوع مرجعي ، يتم إجراء تحويل unboxing (§5.1.8).

ينطبق الترويج الرقمي الثنائي على العديد من المشغلين الرقميين ، بما في ذلك "مشغلي المساواة العددية == و! =."

JLS §15.21.1 (يحدد مشغلو المساواة العددية == و! =):

إذا كانت معاملات مشغل المساواة كلاهما من النوع الرقمي ، أو واحد من النوع الرقمي والآخر قابل للتحويل (§5.1.8) إلى النوع الرقمي ، يتم إجراء الترويج الرقمي الثنائي على المعاملات (§5.6.2).

فى المقابل، JLS §15.21.3 (مشغلات المساواة المرجعية == و! =) توفر:

إذا كانت معاملات مشغل المساواة كلاهما من النوع المرجعي أو النوع الفارغ ، فإن العملية هي مساواة الكائن

هذا يناسب الفهم المشترك للملاكمة والملاكمة ، وهذا يتم ذلك فقط عندما يكون هناك عدم تطابق.

نصائح أخرى

سأشرح أولاً على وجه التحديد == هو مساواة مرجعية ، و على وجه التحديد إنها مساواة رقمية. الشروط للمساواة المرجعية أبسط ، لذلك سيتم شرحها أولاً.

JLS 15.21.3 مشغلي المساواة المرجعية == و !=

إذا كانت المعاملات لمشغل المساواة هي إما من النوع المرجعي أو باطل اكتب ، ثم العملية هي مساواة الكائن.

هذا ما يفسر ما يلي:

System.out.println(new Integer(0) == new Integer(0)); // "false"

كلا المعاملين Integer, ، وهي أنواع مرجعية ، ولهذا السبب == هو مقارنة المساواة المرجعية ، واثنان new الكائنات لن تكون أبدا == لبعضهم البعض ، ولهذا السبب يطبع false.

ل == أن تكون مساواة رقمية ، يجب أن يكون أحد المعامل على الأقل نوعًا رقميًا; ؛ تم تحديد هذا على النحو التالي:

JLS 15.21.1 مشغلي المساواة العددية == و !=

إذا كانت معاملات مشغل المساواة على حد سواء من النوع الرقمي ، أو واحد هو من النوع الرقمي و الآخر قابل للتحويل إلى النوع الرقمي ، يتم إجراء الترويج الرقمي الثنائي على المعاملات. إذا كان النوع الذي تمت ترقيته من المعاملات int أو long, ، ثم يتم إجراء اختبار مساواة عدد صحيح ؛ إذا كان النوع الذي تمت ترقيته هو float orDouble` ، ثم يتم إجراء اختبار المساواة في نقطة العائمة.

لاحظ أن الترويج الرقمي الثنائي يؤدي تحويل قيمة مجموعة وتحويل إلغاء التفسير.

وبالتالي ، فكر فيما يلي:

System.out.println(new Integer(0) == 0); // "true"

هذه المطبوعات true, ، لان:

  • المعامل الصحيح هو رقمي int يكتب
  • المعامل الأيسر قابلة للتحويل إلى نوع رقمي ، عن طريق إلغاء التزامن إلى int
  • وبالتالي == هي عملية المساواة العددية

ملخص

  • إذا كان كلا المعاملين == و != هي أنواع مرجعية ، ستكون دائمًا عملية مساواة مرجعية
    • لا يهم ما إذا كانت المعاملات قابلة للتحويل إلى أنواع رقمية
  • إذا كان أحد المعامل على الأقل نوعًا رقميًا ، فسيكون دائمًا عملية مساواة رقمية
    • سيتم إجراء عملية غير مربحة تلقائية على واحد (على الأكثر!) من المعاملات إذا لزم الأمر

مراجع

أسئلة ذات صلة

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top