مقارنة أعضاء التعداد في Java: == أو يساوي ()؟



Answers

هل يمكن استخدام == على enum ؟

نعم: يحتوي التعداد على عناصر تحكم ضيقة تسمح لك باستخدام == لمقارنة المثيلات. إليك الضمان الذي توفره مواصفات اللغة (التأكيد الخاص بي):

JLS 8.9 التعدادات

نوع التعداد ليس له مثيلات أخرى غير تلك المعرفة بواسطة ثوابته التعدادية.

وهو خطأ وقت التحويل إلى محاولة إنشاء نوع التعداد بشكل صريح. تضمن طريقة final clone في Enum عدم استنساخ ثوابت enum أبداً ، وتضمن المعالجة الخاصة من قبل آلية التسلسل عدم إنشاء حالات مكررة أبدًا كنتيجة لعملية إلغاء التسلسل. يحظر إنشاء انعكاس لأنواع التعداد. وتكفل هذه الأمور الأربعة مجتمعة عدم وجود حالات لنوع enum يتجاوز تلك التي تحددها ثوابت enum .

نظرًا لوجود مثيل واحد فقط لكل ثابت enum ، يجوز استخدام عامل == بدلاً من طريقة equals عند مقارنة مرجعين للكائن إذا كان معروفًا أن إحداها على الأقل يشير إلى ثابت enum . (طريقة equals في Enum هي طريقة final تستدعي فقط super.equals في super.equals وترجع النتيجة ، وبالتالي إجراء مقارنة للهوية.)

هذا الضمان قوي بما فيه الكفاية بحيث يوصي Josh Bloch ، إذا كنت تصر على استخدام نمط singleton ، فإن أفضل طريقة لتنفيذ ذلك هي استخدام تعداد مفرد العنصر (انظر: Java الإصدار الثاني الفعال ، العنصر 3: فرض خاصية singleton مع منشئ خاص أو نوع التعداد ؛ أيضا سلامة الصفحات في سينجلتون )

ما هي الاختلافات بين == و equals ؟

للتذكير ، يجب أن يقال أن == ليس بديلاً صالحًا equals . عندما يكون ، مع ذلك (مثل enum ) ، هناك enum مهمان يجب أخذهما في الاعتبار:

== لا يلقي أبدا NullPointerException

enum Color { BLACK, WHITE };

Color nothing = null;
if (nothing == Color.BLACK);      // runs fine
if (nothing.equals(Color.BLACK)); // throws NullPointerException

== يخضع للتحقق من نوع التوافق في وقت الترجمة

enum Color { BLACK, WHITE };
enum Chiral { LEFT, RIGHT };

if (Color.BLACK.equals(Chiral.LEFT)); // compiles fine
if (Color.BLACK == Chiral.LEFT);      // DOESN'T COMPILE!!! Incompatible types!

ينبغي == أن تستخدم عند الاقتضاء؟

يذكر Bloch على وجه التحديد أن الطبقات الثابتة التي لها السيطرة المناسبة على حالاتها يمكن أن تضمن لعملائها أن == قابلة للاستخدام. enum المذكور على وجه التحديد لتمثيل.

البند 1: النظر في أساليب المصنع ثابتة بدلا من الصانعين

[...] أنها تسمح لطبقة ثابتة بأن تضمن عدم وجود حالتين متساويتين: a.equals(b) إذا وفقط إذا كانت a==b . إذا قامت إحدى الفئات بإجراء هذه الضمانات ، فيمكن لعملائها استخدام عامل التشغيل == بدلاً من طريقة equals(Object) ، مما قد يؤدي إلى تحسين الأداء. توفر أنواع التعداد هذا الضمان.

لتلخيص ، الحجج لاستخدام == على enum هي:

  • إنها تعمل.
  • انه اسرع.
  • إنها أكثر أمانًا في وقت التشغيل.
  • إنها أكثر أمانًا في وقت الترجمة.
Question

وأنا أعلم أن التعدادات جافا يتم تجميعها لفصول مع منشئات خاصة وحفنة من أعضاء ثابت العامة. عند مقارنة عضوين من تعداد معين ، كنت دائمًا أستخدم .equals() ، على سبيل المثال

public useEnums(SomeEnum a)
{
    if(a.equals(SomeEnum.SOME_ENUM_VALUE))
    {
        ...
    }
    ...
}

ومع ذلك ، صادفت فقط بعض التعليمات البرمجية التي تستخدم عامل equals == بدلاً من .equals ():

public useEnums2(SomeEnum a)
{
    if(a == SomeEnum.SOME_ENUM_VALUE)
    {
        ...
    }
    ...
}

ما هو المشغل الذي يجب أن أستخدمه؟




استخدام أي شيء آخر غير == لمقارنة ثواب التعداد هو هراء. إنها تشبه مقارنة كائنات class equals - لا تفعل ذلك!

ومع ذلك ، كان هناك خطأ مقرف (BugId 6277781 ) في Sun JDK 6u10 وأقدم في وقت سابق قد يكون مثيرا للاهتمام لأسباب تاريخية. منع هذا الخطأ الاستخدام الصحيح ل == على en Enemialized enumsial ، على الرغم من أن هذا يمكن القول إلى حد ما من حالة الزاوية.




باختصار ، كلاهما له إيجابيات وسلبيات.

من ناحية ، لديها مزايا لاستخدام == ، كما هو موضح في الإجابات الأخرى.

من ناحية أخرى ، إذا كنت لأي سبب من الأسباب تحل محل الترجمات بنهج مختلف (نماذج الطبقة العادية) ، بعد أن استخدمت == يعضك. (BTDT).




في حالة التعداد كلاهما الصحيح واليمين!




وكما قال الآخرون ، فإن كلا من == و .equals() يعمل في معظم الحالات. إن وقت التأكد من أنك لا تقارن أنواعًا مختلفة تمامًا من الكائنات التي أشار إليها الآخرون هي صحيحة ومفيدة ، إلا أنه يمكن أيضًا العثور على نوع معين من الأخطاء التي تقارن بين نوعين من أنواع التجميع المختلفة بواسطة FindBugs (وربما عمليات فحص وقت Eclipse / IntelliJ) ، لذلك لا يضيف مترجم Java العثور عليه الكثير من الأمان الإضافي.

ومع ذلك:

  1. حقيقة أن == أبدا يرمي في NPE في رأيي هو عيب == . يجب ألا تكون هناك حاجة لأن تكون أنواع enum null ، نظرًا لأنه لا يمكن إضافة أي حالة إضافية قد ترغب في التعبير عنها عبر قيمة null إلى enum كمثيل إضافي. إذا كانت null بشكل غير متوقع ، فما استقاموا لكم فاستقيموا بدلا يكون NPE من == بصمت يقيمون إلى false. لذلك أنا اختلف مع أنها أكثر أمانا في رأي وقت التشغيل . من الأفضل أن ندخل في العادة ألا نترك قيم enum تكون @Nullable .
  2. الحجة التي تقول إن == أسرع هي أيضا مزيفة. في معظم الحالات ستقوم بالاتصال .equals() على متغير نوع وقت التحويل الخاص به هو فئة التعداد ، وفي هذه الحالات ، يمكن أن يعرف المحول البرمجي أن هذا هو نفس == (لأن طريقة enum equals() enum يمكن لا يمكن تجاوزها) ويمكن تحسين استدعاء وظيفة بعيدا. لست متأكداً مما إذا كان المترجم يقوم بذلك حالياً ، ولكن إذا لم يحدث ذلك ، وتبين أنه مشكلة في الأداء في Java بشكل عام ، فعندئذ سأقوم بإصلاح المترجم بدلاً من أن يغير 100000 مبرمج جافا أسلوبهم في البرمجة ليتلائم خصائص أداء إصدار مترجم معين.
  3. enums هي كائنات. بالنسبة لجميع أنواع الكائنات الأخرى ، تكون المقارنة القياسية .equals() ، وليس == . أعتقد أنه من الخطير أن نستثني من enums لأنك قد ينتهي بك الأمر بمقارنة الكائنات بـ == بدلاً من equals() ، خاصة إذا قمت بتعداد enum في فئة غير تعداد. في حالة إعادة البناء ، فإن نقطة العمل من الأعلى خاطئة. لإقناع نفسك أن استخدام == صحيح ، تحتاج إلى التحقق مما إذا كانت القيمة في السؤال إما enum أم بدائيًا ؛ إذا كانت فئة غير enum ، فستكون خاطئة ولكن من السهل أن تفوتها لأن التعليمة البرمجية سوف تستمر في التجميع. والحالة الوحيدة التي يكون فيها استخدام .equals() خاطئًا إذا كانت القيم المعنية .equals() ؛ في هذه الحالة ، لن يتم تجميع الشفرة ، لذا من الصعب تفويتها. وبالتالي ، فإن .equals() أسهل بكثير في التعرف على أنه صحيح ، وأكثر أمانًا ضد الرواسب المستقبلية.

أعتقد فعلا أن لغة جافا يجب أن تكون محددة == على كائنات للاتصال .equals () على قيمة اليد اليسرى ، وإدخال عامل تشغيل منفصل لهوية الكائن ، ولكن هذا ليس كيف تم تعريف Java.

باختصار ، ما زلت أعتقد أن الحجج هي لصالح استخدام .equals() لأنواع enum .




يمكنك استخدام: == ، يساوي () أو تبديل () كتلة لمقارنة Enums ، كلها صحيحة من الناحية الفنية ، وسوف تخدم حاجتك.

تحقق من هذا البرنامج التعليمي لمعرفة المزيد حول العمليات الشائعة لـ Enum: كيفية استخدام Enums في java




التعداد في المنتصف عبارة عن مجموعة من الأعداد الصحيحة الثابتة. "==" صحيحة وسليمة تمامًا كما لو كنت تقارن بين عددين.




Related



Tags

java java   enums