سؤال

لدي وظيفة تقوم بإرجاع رقم معرف إذا كانت الوسيطة موجودة في قاعدة البيانات. إذا لم يكن كذلك ، فإنه يعود فارغة. هل هذا يتسول لاستثناء مؤشر فارغ؟ لا يُسمح بأرقام الهوية السلبية ، لكنني اعتقدت أنه سيكون من الواضح أن تضع وسيطات غير موجودة إرجاع خالية بدلاً من رمز الخطأ مثل -1. ما رأيك؟

private Integer tidOfTerm(String name) throws SQLException {
    String sql = "SELECT tid FROM term_data WHERE name = ?";
    PreparedStatement prep = conn.prepareStatement(sql);
    prep.setString(1, name);
    ResultSet result = prep.getResultSet();

    if (result.next()) {
        return result.getInt("tid");
    }

    return null; // TODO: is this begging for a null pointer exception?
}
هل كانت مفيدة؟

المحلول

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

نصائح أخرى

العودة أ null في حالة البحث الذي لا يعطي نتيجة هو وسيلة طبيعية لتمثيل عدم وجود. سأختارها في هذه الحالة. (أساليب البحث لفئات خريطة Java القياسية هي مثال لاستخدام null في حالة عدم احتواء الخريطة على مفتاح.)

أما بالنسبة لإعادة قيمة خاصة للمعرف ، فإنني أقترح فقط القيام بذلك إذا كان نظامك يحتوي بالفعل على قيم خاصة تعيد تحديد معرف خاص.

غالبًا ما يكون الاحتمال الذي يسمعه آخر هو إلقاء استثناء في هذه الحالة. ليس من الحكمة استخدام استثناءات لتمرير الحالة ، لذلك لن أفعل ذلك أيضًا.

أعتقد أنه من المشروع إعادة فارغ في هذه الحالة. فقط تأكد من توثيق النية بشكل صحيح.

سيكون إرجاع قيمة سلبية في هذه الحالة على ما يرام ، لكنه ليس حلاً شاملًا. ماذا لو تم السماح بالقيم السلبية في DB؟

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

آمل ألا تكون هذه طريقة حقيقية لك. أنت لا تغلق البيان أو النتيجة في نطاق الطريقة.

  • لا تستخدم رمز الخطأ! ما هي القيمة الخطأ؟ لن تصبح قيمة عائد قانونية أبدًا؟ لا شيء فاز.

  • فارغة ليست جيدة. يتعين على معظم رمز المتصل القيام بفحص فارغ للنتيجة. وفي بعض الأحيان قد يعود SELECT NULL. هل يجب التعامل معه مختلفًا عن عدم وجود صف؟

  • رمي استثناء مثل nosuchelementException بدلا من عودة فارغة. إنه استثناء لم يتم التحقق منه ، يمكن للمتصل التعامل معه أو تمريره. وإذا أراد المتصل التعامل ، فإن Try Catch ليس أكثر تعقيدًا من If Null.

أقترح عليك التفكير في نمط الخيار.

يعمل نمط الخيار كركب حول النوع الذي تم إرجاعه ، ويحدد حالتين خاصتين: الخيار. none () و Option.some (). وبهذه الطريقة ، تعرف دائمًا نوعك الذي تم إرجاعه (خيار) ، ويمكنك التحقق مما إذا كان لديك قيمة في كائن الخيار الذي تم إرجاعه باستخدام طرق مثل Option.issome () و Option.isnone ().

وبهذه الطريقة ، يمكنك أن تضمن أنه ليس لديك أي خالية غير محددة.

بالطبع ، كل هذا يأتي على حساب تعقيد الكود الإضافي.

لمزيد من المعلومات حول نوع الخيار ، انظر هنا (رمز سكالا ، ولكن نفس المدير)

لا ، لن يفعل ذلك. لن يرمي سوى NPE إذا قمت بعمله بعد ذلك كما لو كان بدائيًا بدون فحصه. على سبيل المثال i++ وهلم جرا. مثالك صالح (توقع من أن رمز JDBC نفسه هو تسرب الموارد). إذا لم تكن بحاجة إلى الفعلي id, ، ثم يمكنك من ناحية أخرى أيضًا إرجاع أ boolean.

قد يسبب مشكلة كبيرة للمستخدمين المبتدئين. سوف يدرك المبرمجين الجيدون أنه إذا كان الاسم غير صالح بعد ذلك null قد يتم إرجاعها. بعد قولي هذا كل ما هو أكثر قياسية هو رمي البعض exception.

قد تكون صعبة في مزيج من autoboxing. إذا كنت أفعل هذا:

final int tid = tidForTerm("term");

و "المصطلح" غير موجود ، سأحصل على NPE ، لأن Java تحاول إلغاء صندوق عدد صحيح (NULL) إلى int بدائية.

ومع ذلك ، هناك حالات يكون فيها من الجيد استخدام Null للأعداد الصحيحة. في الكيانات التي لها قيم int اختيارية ، على سبيل المثال عدد سكان المدينة. في هذه الحالة ، يعني NULL ، لا توجد معلومات متاحة.

مشكلة مثيرة للاهتمام وعدد كبير من الحلول الممكنة:

  1. قم بإنشاء طريقة hasargument وطلب من المستخدمين الاتصال بها ، وقد يكون هذا الأمر بطيئًا و dupplicate
  2. رمي استثناء إذا لم تكن القيمة في قاعدة البيانات ، يجب استخدامها فقط إذا كان هذا غير متوقع
  3. استخدم قيمًا إضافية للإشارة إلى عائد غير صالح ، وستعمل القيم الخالية والسلبية من أجلك ، لكن إذا لم يتم التحقق منها ، فقد تتسبب في مشاكل في وقت لاحق في الكود.
  4. ارجع غلافًا باستخدام طريقة ISValid () وطريقة getValue () ، حيث يلقي GetValue () استثناء عندما يكون غير صالح. هذا من شأنه أن يحل مشاكل 1 و 3 ، ولكن قد يكون قليلا جدا.

أود أن أقول أن الحل الأفضل يعتمد على ما تم تسمية طريقتك ، ويجب أن تفكر في تسمية أساليبك بقدر ما إذا كان ينبغي عليهم العودة لاغية أو رمي استثناء.

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

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

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

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

من فضلك لا تكتب الرمز الذي يرجع خالية. هذا يعني أن كل مكالمة إلى الكود الخاص بك يجب تحقق من NULL حتى تكون قوية. كل مره. دائماً.

فكر في إرجاع قائمة بدلاً من ذلك تحتوي على عدد من قيم الإرجاع ، والتي قد تكون صفرًا.

نعم ، يجب أن تسبب NPE ونعم يجب أن تصطاد ذلك في طريقة الاتصال (أو مكان مناسب آخر). السبب الأكثر ترجيحًا لعودة طريقتك في NULL هو عندما لا توجد سجلات والطريقة الصحيحة للتعامل مع ذلك من خلال رمي استثناء. والاستثناء المثالي لإخبار شخص ما ليس لديك ما طلبه هو NPE.

إرجاع رمز الخطأ (على سبيل المثال -1) ليس جيدًا لأن:

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

ب) في المستقبل إذا أصبح -1 معرف مصطلح قانوني ، فسيكون من الصعب تغييره (إذا كان يجب عليك استخدام -1 ، ثم (تحرير: في C) على الأقل ، قم بتعريف Define Dewse -1 واستخدام ErrorCode في كل مكان)

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