هل يجب ألا أستخدم الأنواع البدائية مرة أخرى؟

StackOverflow https://stackoverflow.com/questions/124148

  •  02-07-2019
  •  | 
  •  

سؤال

يمكن أن يؤدي الخلط بين استخدام أنواع البيانات البدائية وفئات التغليف الخاصة بها في Java إلى الكثير من الأخطاء.المثال التالي يوضح المشكلة:

int i = 4;
...
if (i == 10)
  doStuff();

في وقت لاحق تكتشف أنك تريد المتغير أنا إما أن تكون محددة أو غير محددة، لذلك يمكنك تغيير الإنشاء أعلاه إلى:

Integer i = null;

الآن فشل التحقق من المساواة.

هل من الممارسات الجيدة في Java استخدام فئات الغلاف البدائية دائمًا؟من الواضح أنه سيزيل بعض الأخطاء مبكرًا، ولكن ما هي الجوانب السلبية لذلك؟هل يؤثر ذلك على الأداء أو على مساحة ذاكرة التطبيق؟هل هناك أي مسكتك متستر؟

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

المحلول

استخدام الأنواع المعبأة يفعل لديك مشاكل في الأداء والذاكرة.

عند إجراء المقارنات (على سبيل المثال (i == 10) )، يجب أن تقوم Java بإلغاء تحديد النوع قبل إجراء المقارنة.حتى باستخدام i.equals(TEN) يستخدم استدعاء الأسلوب، وهو أكثر تكلفة و(IMO) أقبح من بناء الجملة ==.

فيما يتعلق بالذاكرة، يجب تخزين الكائن في الكومة (والذي يؤثر أيضًا على الأداء) بالإضافة إلى تخزين القيمة نفسها.

مسكتك متستر؟ i.equals(j) عندما أكون null.

أنا دائمًا أستخدم البدائيين، إلا عندما يكون ذلك يمكن يكون null, ، ولكن تحقق دائمًا من ذلك null قبل المقارنة في تلك الحالات.

نصائح أخرى

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

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

أقترح استخدام البدائيين طوال الوقت ما لم يكن لديك بالفعل مفهوم "فارغ".

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

بالنسبة إلى التعويم/الزوجي، يمكنك معاملة NaN على أنها فارغة، لكن تذكر أن NaN != NaN لذلك لا تزال بحاجة إلى عمليات فحص خاصة مثل !Float.isNaN(x).

سيكون من الرائع حقًا لو كانت هناك مجموعات تدعم الأنواع البدائية بدلاً من الاضطرار إلى إضاعة الوقت/النفقات العامة للملاكمة.

في المثال الخاص بك، ستكون عبارة if على ما يرام حتى تتجاوز 127 (حيث أن نظام Integer autoboxing سوف يقوم بتخزين قيم تصل إلى 127 ويعيد نفس المثيل لكل رقم يصل إلى هذه القيمة)

لذا فالأمر أسوأ من تقديمه..

if( i == 10 )

سوف تعمل كما كان من قبل، ولكن

if( i == 128 )

سوف تفشل.ولأسباب كهذه، أقوم دائمًا بإنشاء كائنات بشكل صريح عندما أحتاج إليها، وأميل إلى الالتزام بالمتغيرات البدائية إذا كان ذلك ممكنًا

أنواع Java POD موجودة لسبب ما.بالإضافة إلى النفقات العامة، لا يمكنك القيام بعمليات عادية مع الكائنات.العدد الصحيح هو كائن يجب تخصيصه وجمع البيانات المهملة.كثافة العمليات ليست كذلك.

إذا كانت هذه القيمة فارغة، فقد تجد أنك في تصميمك بحاجة إلى شيء آخر.

هناك احتمالان--إما أن تكون القيمة مجرد بيانات (لن تعمل التعليمات البرمجية بشكل مختلف إذا تم ملؤها أم لا)، أو أنها تشير فعليًا إلى أن لديك نوعين مختلفين من الكائنات هنا (تعمل التعليمات البرمجية بشكل مختلف إذا كان هناك قيمة من فارغة)

إذا كانت مجرد بيانات للعرض/التخزين، فقد تفكر في استخدام DTO حقيقي - وهو ليس لديه عضو من الدرجة الأولى على الإطلاق.سيكون لدى هؤلاء بشكل عام طريقة للتحقق لمعرفة ما إذا تم تعيين القيمة أم لا.

إذا قمت بالتحقق من القيمة الخالية في مرحلة ما، فقد ترغب في استخدام فئة فرعية لأنه عندما يكون هناك اختلاف واحد، عادة ما يكون هناك المزيد.على الأقل تريد طريقة أفضل للإشارة إلى اختلافك من "if primitiveIntValue == null"، فهذا لا يعني شيئًا حقًا.

لا تتحول إلى غير البدائيين فقط للحصول على هذه التسهيلات.استخدم قيمة منطقية للإشارة إلى ما إذا تم تعيين القيمة أم لا.إذا لم يعجبك هذا الحل وتعلم أن الأعداد الصحيحة الخاصة بك ستكون ضمن حد معقول (أو لا تهتم بالفشل العرضي) فاستخدم قيمة محددة للإشارة إلى "غير مهيأ"، مثل Integer.MIN_VALUE.لكن هذا حل أقل أمانًا بكثير من الحل المنطقي.

عندما وصلت إلى نقطة "لاحقًا"، كان يلزم إنجاز المزيد من العمل أثناء إعادة البناء.استخدم البدائيين عندما يكون ذلك ممكنًا.(فترة رأس المال) ثم قم بإنشاء POJOs إذا كانت هناك حاجة إلى المزيد من الوظائف.في رأيي، يتم استخدام فئات المجمع البدائية بشكل أفضل للبيانات التي تحتاج إلى السفر عبر السلك، وهذا يعني تطبيقات الشبكة.يؤدي السماح بالقيم الخالية كقيم مقبولة إلى حدوث صداع مع "نمو" النظام.الكثير من التعليمات البرمجية الضائعة أو المفقودة، تحرس ما ينبغي أن يكون مقارنات بسيطة.

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