java - تجنب! = عبارات خالية


المصطلح الذي استخدمه أكثر عندما البرمجة في جافا هو اختبار إذا object != null قبل أن استخدامه. هذا لتجنب نولبوانتيركسيبتيون . أجد رمز قبيح جدا، ويصبح غير قابل للقراءة.

هل هناك بديل جيد لهذا؟

أريد أن أتناول ضرورة اختبار كل كائن إذا كنت ترغب في الوصول إلى حقل أو طريقة لهذا الكائن.

فمثلا:

if (someobject != null) {
    someobject.doCalc();
}

في هذه الحالة سوف تجنب NullPointerException ، وأنا لا أعرف بالضبط إذا كان الكائن null أو لا. تظهر هذه الاختبارات في جميع أنحاء بلدي التعليمات البرمجية ونتيجة لذلك.




Answers


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

لوضع هذه طريقة أخرى، هناك حالتين حيث يأتي فحص فارغة:

  1. حيث يكون نول ردا صالحا من حيث العقد؛ و

  2. حيث أنها ليست ردا صالحا.

(2) سهلة. إما استخدام تصريحات assert (تأكيدات) أو السماح الفشل (على سبيل المثال، نولبوانتيركسيبتيون ). التأكيدات هي ميزة جافا عالية الاستغلال التي تمت إضافتها في 1.4. بناء الجملة هو:

assert <condition>

أو

assert <condition> : <object>

حيث <condition> عبارة تعبير منطقي و <object> هو كائن سيتم تضمين مخرجات أسلوب toString() في الخطأ.

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

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

(1) هو أصعب قليلا. إذا لم يكن لديك سيطرة على رمز كنت تتصل ثم كنت عالقة. إذا كان نول ردا صالحا، فعليك التحقق من ذلك.

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

مع عدم جمع قد يكون من الصعب. فكر في ذلك كمثال: إذا كانت لديك هذه الواجهات:

public interface Action {
  void doSomething();
}

public interface Parser {
  Action findAction(String userInput);
}

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

الحل البديل هو عدم إرجاع نول وبدلا من ذلك استخدام نمط كائن فارغ:

public class MyParser implements Parser {
  private static Action DO_NOTHING = new Action() {
    public void doSomething() { /* do nothing */ }
  };

  public Action findAction(String userInput) {
    // ...
    if ( /* we can't find any actions */ ) {
      return DO_NOTHING;
    }
  }
}

قارن:

Parser parser = ParserFactory.getParser();
if (parser == null) {
  // now what?
  // this would be an example of where null isn't (or shouldn't be) a valid response
}
Action action = parser.findAction(someInput);
if (action == null) {
  // do nothing
} else {
  action.doSomething();
}

إلى

ParserFactory.getParser().findAction(someInput).doSomething();

وهو تصميم أفضل بكثير لأنه يؤدي إلى رمز أكثر إيجازا.

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

try {
    ParserFactory.getParser().findAction(someInput).doSomething();
} catch(ActionNotFoundException anfe) {
    userConsole.err(anfe.getMessage());
}

أو إذا كنت تعتقد أن آلية محاولة / قبض قبيحة جدا، بدلا من لا شيء يجب أن الإجراء الافتراضي الخاص بك تقديم التغذية الراجعة للمستخدم.

public Action findAction(final String userInput) {
    /* Code to return requested Action if found */
    return new Action() {
        public void doSomething() {
            userConsole.err("Action not found: " + userInput);
        }
    }
}



إذا كنت تستخدم (أو تخطط لاستخدام) جيتبرينز إنتليج إيديا ، جافا إيد، يمكنك استخدام بعض الشروح الخاصة التي وضعتها لهم.

في الأساس، كنت قد حصلت على @Nullable و @NotNull .

يمكنك استخدام في الطريقة والمعلمات، مثل هذا:

@NotNull public static String helloWorld() {
    return "Hello World";
}

أو

@Nullable public static String helloWorld() {
    return "Hello World";
}

المثال الثاني لن يتم تجميع (في إنتليج إيديا).

عند استخدام الدالة helloWorld() الأولى في جزء آخر من التعليمات البرمجية:

public static void main(String[] args)
{
    String result = helloWorld();
    if(result != null) {
        System.out.println(result);
    }
}

الآن مترجم إنتليج إيديا سوف اقول لكم ان الاختيار غير مجدية، لأن helloWorld() وظيفة لن يعود null ، من أي وقت مضى.

استخدام المعلمة

void someMethod(@NotNull someParameter) { }

إذا كنت أكتب شيئا مثل:

someMethod(null);

لن يتم تجميع هذا.

المثال الأخير باستخدام @Nullable

@Nullable iWantToDestroyEverything() { return null; }

فعل هذا

iWantToDestroyEverything().something();

ويمكنك أن تتأكد من أن هذا لن يحدث. :)

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

في إنتليج فكرة 10.5 وعلى، أضافوا الدعم لأي @Nullable @NotNull @Nullable أخرى.

انظر بلوق وظيفة أكثر مرونة وشكلي @ نولابل / @ نوتنول الشروح .




إذا كانت القيم الفارغة غير مسموح بها

إذا كانت الطريقة تسمى خارجيا، فابدأ بشيء من هذا القبيل:

public void method(Object object) {
  if (object == null) {
    throw new IllegalArgumentException("...");
  }

ثم، في بقية هذه الطريقة، ستعرف أن object ليس نول.

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

مثال:

public String getFirst3Chars(String text) {
  return text.subString(0, 3);
}

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

إذا كان لاغيا مسموحا به

هذا يعتمد حقا. إذا وجدت أنني غالبا ما تفعل شيئا من هذا القبيل:

if (object == null) {
  // something
} else {
  // something else
}

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

انها في الواقع نادرة بالنسبة لي لاستخدام لغة " if (object != null && ... ".

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




نجاح باهر، أنا أكره تقريبا لإضافة إجابة أخرى عندما يكون لدينا 57 طرق مختلفة للتوصية NullObject pattern ، ولكن أعتقد أن بعض الناس المهتمين في هذا السؤال قد ترغب في معرفة أن هناك اقتراحا على جدول جافا 7 لإضافة "نول -مناولة آمنة "، وهي عبارة عن بنية مبسطة للمنطق إن لم يكن مساويا.

المثال الذي قدمه أليكس ميلر يشبه هذا:

public String getPostcode(Person person) {  
  return person?.getAddress()?.getPostcode();  
}  

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

تحديث: تم تقديم اقتراح رسمي لمشغل غير آمن في جاوة 7 تحت بروجيكت سوين. بناء الجملة يختلف قليلا عن المثال أعلاه، لكنه نفس المفهوم.

تحديث: اقتراح المشغل فارغة فارغة لم يجعله في مشروع عملة. لذلك، لن ترى هذه البنية في جافا 7.




إذا كانت القيم غير المعرفة غير مسموح بها:

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

إذا كانت القيم غير المعرفة مسموح بها:

إذا كنت تريد تعريف واجهة برمجة تطبيقات جديدة حيث تكون القيم غير المعرفة منطقية ، فاستخدم نمط الخيار (قد يكون مألوفا من اللغات الوظيفية). لديها المزايا التالية:

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

يحتوي جافا 8 على فئة Optional مدمجة (مستحسن)؛ للإصدارات السابقة، هناك بدائل المكتبة، على سبيل المثال Option غوافا الصورة Optional أو فونكتيونال Option . ولكن مثل العديد من أنماط على غرار وظيفية، واستخدام الخيار في جافا (حتى 8) النتائج في بعض تماما النمطية، والتي يمكنك تقليل باستخدام لغة جفم مطول أقل، على سبيل المثال سكالا أو شتيند.

إذا كان لديك للتعامل مع أبي التي قد تعود نولز ، لا يمكنك أن تفعل الكثير في جافا. شتيند و غروفي لديهم مشغل إلفيس ?: و مشغل ديريفيرانس الخالي من السلامة ?. ، ولكن لاحظ أن هذا يعود نول في حالة إشارة نول، لذلك فقط "يحبط" التعامل السليم من نول.




فقط لهذا الوضع - تجنب التحقق من قيمة فارغة قبل سلسلة مقارنة:

if ( foo.equals("bar") ) {
 // ...
}

سوف يؤدي إلى NullPointerException إذا foo غير موجود.

يمكنك تجنب ذلك إذا قارنت String الخاص بك مثل هذا:

if ( "bar".equals(foo) ) {
 // ...
}



مع جافا 8 يأتي الطبقة java.util.Optional الجديدة التي يمكن القول أن يحل بعض المشكلة. يمكن للمرء أن يقول على الأقل أنه يحسن قراءة التعليمات البرمجية، وفي حالة واجهات برمجة التطبيقات العامة جعل عقد أبي أكثر وضوحا لمطور العميل.

وهم يعملون على هذا النحو:

يتم إنشاء كائن اختياري لنوع معين ( Fruit ) كنوع العودة لطريقة. يمكن أن تكون فارغة أو تحتوي على كائن Fruit :

public static Optional<Fruit> find(String name, List<Fruit> fruits) {
   for (Fruit fruit : fruits) {
      if (fruit.getName().equals(name)) {
         return Optional.of(fruit);
      }
   }
   return Optional.empty();
}

الآن ننظر في هذا الرمز حيث نقوم بالبحث في قائمة Fruit ( fruits ) لمثل الفاكهة مثيل:

Optional<Fruit> found = find("lemon", fruits);
if (found.isPresent()) {
   Fruit fruit = found.get();
   String name = fruit.getName();
}

يمكنك استخدام مشغل map() لإجراء حساب على - أو استخراج قيمة من - كائن اختياري. orElse() يتيح لك تقديم قيمة احتياطية للقيم المفقودة.

String nameOrNull = find("lemon", fruits)
    .map(f -> f.getName())
    .orElse("empty-name");

وبطبيعة الحال، فإن التحقق من قيمة فارغة / فارغة لا يزال ضروريا، ولكن على الأقل المطور يدرك أن القيمة قد تكون فارغة وخطر النسيان للتحقق محدودة.

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

وبطبيعة الحال يمكن أيضا استخدام Optional كوسيطة الأسلوب، وربما طريقة أفضل للإشارة إلى وسيطات اختياري من 5 أو 10 طرق التحميل الزائد في بعض الحالات.

عروض Optional طرق أخرى مريحة، مثل orElse التي تسمح باستخدام القيمة الافتراضية، و ifPresent الذي يعمل مع عبارات لامدا .

أدعوكم لقراءة هذه المقالة (المصدر الرئيسي لكتابة هذه الإجابة) التي يتم فيها توضيح المشكلة NullPointerException (وبصفة عامة مؤشر نول) وكذلك الحل (جزئي) الذي تم تقديمه بواسطة Optional بشكل جيد: جافا أوبتيونال أوبجيكتس .




اعتمادا على نوع الأشياء التي تقوم بفحصها، قد تكون قادرا على استخدام بعض الفئات في المشاعات اباتشي مثل: اباتشي كومونس لانغ و أباتشي كومونس كولكتيونس

مثال:

String foo;
...
if( StringUtils.isBlank( foo ) ) {
   ///do something
}

أو (اعتمادا على ما تحتاج إلى التحقق):

String foo;
...
if( StringUtils.isEmpty( foo ) ) {
   ///do something
}

فئة سترينغوتيلز هي واحدة فقط من العديد؛ هناك عدد قليل جدا من الطبقات الجيدة في المشاعات التي لا تلاعب آمنة خالية.

فيما يلي مثال على كيفية استخدام فاليداتيون فارغة في جافا عند تضمين مكتبة أباتشي (كومونس-لانغ-2.4.jar)

public DOCUMENT read(String xml, ValidationEventHandler validationEventHandler) {
    Validate.notNull(validationEventHandler,"ValidationHandler not Injected");
    return read(new StringReader(xml), true, validationEventHandler);
}

وإذا كنت تستخدم الربيع، والربيع أيضا لديه نفس الوظيفة في حزمة، انظر مكتبة (الربيع-2.4.6.jar)

مثال على كيفية استخدام هذا كلاسف ثابت من الربيع (org.springframework.util.Assert)

Assert.notNull(validationEventHandler,"ValidationHandler not Injected");



  • إذا كنت تعتبر كائن لا ينبغي أن يكون نول (أو أنه علة) استخدام تأكيد.
  • إذا كان الأسلوب الخاص بك لا يقبل معلمات فارغة تقول في جافادوك واستخدام تأكيد.

يجب عليك التحقق من الكائن! = نول فقط إذا كنت تريد التعامل مع الحالة حيث قد يكون الكائن فارغ ...

هناك اقتراح لإضافة تعليقات توضيحية جديدة في Java7 للمساعدة في معلمات نول / نولن: http://tech.puredanger.com/java7/#jsr308




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




يوفر إطار مجموعات غوغل طريقة جيدة وأنيقة لتحقيق الاختيار الفارغ.

هناك طريقة في فئة المكتبة مثل هذا:

static <T> T checkNotNull(T e) {
   if (e == null) {
      throw new NullPointerException();
   }
   return e;
}

والاستخدام هو (مع import static ):

...
void foo(int a, Person p) {
   if (checkNotNull(p).getAge() > a) {
      ...
   }
   else {
      ...
   }
}
...

أو في المثال الخاص بك:

checkNotNull(someobject).doCalc();



في بعض الأحيان، لديك أساليب تعمل على المعلمات التي تحدد عملية متماثلة:

a.f(b); <-> b.f(a);

إذا كنت تعرف ب لا يمكن أبدا أن تكون فارغة، يمكنك فقط مبادلة ذلك. هو الأكثر فائدة ل يساوي: بدلا من foo.equals("bar"); أفضل القيام "bar".equals(foo); .




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

عندما يتم طرح الاستثناء، فحص تتبع المكدس والعمل من خلال الخطأ.




جافا 7 يحتوي على فئة الأداة المساعدة java.util.Objects جديدة التي يوجد أسلوب requireNonNull() . كل هذا لا رمي NullPointerException إذا كانت NullPointerException خالية، ولكن ينظف التعليمات البرمجية قليلا. مثال:

Objects.requireNonNull(someObject);
someObject.doCalc();

الطريقة هي الأكثر فائدة للتحقق فقط قبل تخصيص في منشئ، حيث كل استخدام منه يمكن أن ينقذ ثلاثة أسطر من التعليمات البرمجية:

Parent(Child child) {
   if (child == null) {
      throw new NullPointerException("child");
   }
   this.child = child;
}

يصبح

Parent(Child child) {
   this.child = Objects.requireNonNull(child, "child");
}



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

  1. ل"مسألة غير معروف" إعطاء "الإجابة غير معروفة". (كن خالية آمنة حيث هذا هو الصحيح من جهة نظر رجال الأعمال) فحص الحجج لاغية مرة واحدة داخل الأسلوب قبل استخدام يخفف المتصلين متعددة من التحقق منها قبل إجراء المكالمة.

    public Photo getPhotoOfThePerson(Person person) {
        if (person == null)
            return null;
        // Grabbing some resources or intensive calculation
        // using person object anyhow.
    }

    يؤدي السابقة لتدفق المنطق الطبيعي للحصول على أي صورة لصديقة غير موجودة من مكتبة الصور الخاصة بي.

    getPhotoOfThePerson(me.getGirlfriend())

    وتناسبها مع API جافا جديد المقبلة (تتطلع)

    getPhotoByName(me.getGirlfriend()?.getName())

    في حين أنه هو بالأحرى "تدفق الأعمال العادي" لا للعثور على الصور المخزنة في DB لشخص، اعتدت على استخدام أزواج مثل أدناه للحصول على بعض الحالات الأخرى

    public static MyEnum parseMyEnum(String value); // throws IllegalArgumentException
    public static MyEnum parseMyEnumOrNull(String value);

    ولا تستنكف لكتابة <alt> + <shift> + <j>(توليد جافادوك في الكسوف) وكتابة ثلاث كلمات إضافية بالنسبة لك API العام. هذا وسوف تكون أكثر من كافية للجميع ولكن أولئك الذين لا يقرأون الوثائق.

    /**
     * @return photo or null
     */

    أو

    /**
     * @return photo, never null
     */
  2. هذا هو بالأحرى حالة النظرية وفي معظم الحالات يجب عليك تفضل API آمن جافا لاغية، ولكن NullPointerExceptionهي فئة فرعية ل Exception. وبالتالي فإنه هو شكل من أشكال Throwableأن يشير إلى الظروف التي طلب معقول قد ترغب في التقاط ( جافادوك )! لاستخدام الأولى الأكثر استفادة من الاستثناءات ومنفصلة رمز من رمز 'العادية' معالجة الأخطاء ( وفقا للمبدعين من جاوة ) فمن المناسب، وبالنسبة لي، للقبض NullPointerException.

    public Photo getGirlfriendPhoto() {
        try {
            return appContext.getPhotoDataSource().getPhotoByName(me.getGirlfriend().getName());
        } catch (NullPointerException e) {
            return null;
        }
    }

    يمكن أن تنشأ الأسئلة:

    س: ماذا لو getPhotoDataSource()باطلة عوائد؟
    A. والأمر متروك منطق الأعمال. لو فشلت في العثور على ألبوم صور سأريكم أي صور. ماذا لو لم يتم تهيئة appContext؟ منطق الأعمال هذه الطريقة ليضع مع هذا. إذا كان نفس المنطق ينبغي أن تكون أكثر صرامة ثم رمي استثناء بل هو جزء من منطق الأعمال والاختيار واضح لاغية وينبغي أن تستخدم (حالة 3). و API جديد جافا خالية آمنة يناسب أفضل هنا لتحديد بشكل انتقائي ما يعني وما لا يعني ليتم تهيئتها لتكون من الفشل بسرعة في حالة وجود أخطاء مبرمج.

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

    Q. هذا النهج جزاء أداء بسبب افتتاح إغلاق المحاولة.
    A. البرامج يجب أن يكون من السهل أن نفهم وتعديل أولا. فقط بعد ذلك، يمكن للمرء التفكير في الأداء، وفقط إذا لزم الأمر! وعند الحاجة! ( مصدر )، وغيرها الكثير).

    PS.وهذا النهج سوف تكون معقولة لاستخدام مثل رمز معالجة الأخطاء منفصل عن "العادية" مدونة المبدأ هو معقول لاستخدامها في مكان ما. النظر في المثال التالي:

    public SomeValue calculateSomeValueUsingSophisticatedLogic(Predicate predicate) {
        try {
            Result1 result1 = performSomeCalculation(predicate);
            Result2 result2 = performSomeOtherCalculation(result1.getSomeProperty());
            Result3 result3 = performThirdCalculation(result2.getSomeProperty());
            Result4 result4 = performLastCalculation(result3.getSomeProperty());
            return result4.getSomeProperty();
        } catch (NullPointerException e) {
            return null;
        }
    }
    
    public SomeValue calculateSomeValueUsingSophisticatedLogic(Predicate predicate) {
        SomeValue result = null;
        if (predicate != null) {
            Result1 result1 = performSomeCalculation(predicate);
            if (result1 != null && result1.getSomeProperty() != null) {
                Result2 result2 = performSomeOtherCalculation(result1.getSomeProperty());
                if (result2 != null && result2.getSomeProperty() != null) {
                    Result3 result3 = performThirdCalculation(result2.getSomeProperty());
                    if (result3 != null && result3.getSomeProperty() != null) {
                        Result4 result4 = performLastCalculation(result3.getSomeProperty());
                        if (result4 != null) {
                            result = result4.getSomeProperty();
                        }
                    }
                }
            }
        }
        return result;
    }

    PPS.بالنسبة لأولئك بسرعة لdownvote (وليس بهذه السرعة لقراءة الوثائق) وأود أن أقول إنني لم يسبق القبض على استثناء خالية مؤشر (NPE) في حياتي. ولكن هذا الاحتمال كان يهدف عمدا من قبل المبدعين جافا لNPE هو فئة فرعية من Exception. لدينا سابقة في التاريخ جافا عندما ThreadDeathهو Errorليس لأنه هو في الواقع خطأ التطبيق، ولكن فقط لأنه لم يكن يقصد به أن تكون اشتعلت! كم NPE يناسب أن يكون Errorمن ThreadDeath! ولكنها ليست كذلك.

  3. التحقق من وجود "لا توجد بيانات" إلا إذا منطق الأعمال يعني ذلك.

    public void updatePersonPhoneNumber(Long personId, String phoneNumber) {
        if (personId == null)
            return;
        DataSource dataSource = appContext.getStuffDataSource();
        Person person = dataSource.getPersonById(personId);
        if (person != null) {
            person.setPhoneNumber(phoneNumber);
            dataSource.updatePerson(person);
        } else {
            Person = new Person(personId);
            person.setPhoneNumber(phoneNumber);
            dataSource.insertPerson(person);
        }
    }

    و

    public void updatePersonPhoneNumber(Long personId, String phoneNumber) {
        if (personId == null)
            return;
        DataSource dataSource = appContext.getStuffDataSource();
        Person person = dataSource.getPersonById(personId);
        if (person == null)
            throw new SomeReasonableUserException("What are you thinking about ???");
        person.setPhoneNumber(phoneNumber);
        dataSource.updatePerson(person);
    }

    إذا لم يتم تهيئة appContext أو مصدر بيانات غير معالج وقت NullPointerException سوف يقتل الترابط الحالي، وستتم معالجته من قبل Thread.defaultUncaughtExceptionHandler (بالنسبة لك لتحديد واستخدام مسجل المفضلة لديك أو غيرها من mechanizm الإخطار). إذا لم يتم تغيير، ThreadGroup # uncaughtException ستطبع تتبع مكدس الذاكرة المؤقتة ليخطئ النظام. ينبغي للمرء أن مراقبة سجل خطأ تطبيق ثم فتح قضية جيرة لكل استثناء غير معالج الذي هو في الواقع خطأ في التطبيق. مبرمج يجب إصلاح الخلل في مكان ما في الاشياء التهيئة.




في نهاية المطاف، والطريقة الوحيدة لحل هذه المشكلة بشكل كامل عن طريق استخدام لغة البرمجة المختلفة:

  • في الهدف C، يمكنك أن تفعل ما يعادل الاحتجاج على طريقة nil، وقطعا لن يحدث شيء. وهذا يجعل من الشيكات معظم فارغة لا لزوم لها، لكنها يمكن أن تجعل الأخطاء أصعب بكثير لتشخيص.
  • في نيس ، وهي لغة مشتقة جافا، هناك إصداران من جميع الأنواع: نسخة يحتمل أن تكون لاغية ونسخة يست فارغة. يمكنك فقط استدعاء الأساليب على أنواع يست فارغة. أنواع يحتمل أن تكون فارغة يمكن تحويلها إلى أنواع يست فارغة من خلال فحص واضح لاغية. وهذا يجعل من الاسهل بكثير أن تعرف أين هي الضوابط اللازمة لاغية، وحيث انهم ليسوا كذلك.



مشتركة "مشكلة" في جاوة في الواقع.

أولا، أفكاري على هذا:

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

لذلك، يجب أن يكون IMHO، لاغية خطأ فادح والذي يحول دون مزيد من التنفيذ (أي، حيث باطلة ليست قيمة صالحة).

الطريقة يمكنني حل هذه المشكلة هي هذه:

أولا، أنا أتبع هذه الاتفاقية:

  1. جميع الطرق العامة / API دائما للتأكد من حججها لاغية
  2. جميع طرق خاصة لا تحقق لاغية لأنها تسيطر أساليب (مجرد السماح يموت مع استثناء nullpointer في حال لم تتم معالجة أعلاه)
  3. الطرق الأخرى الوحيدة التي لا تحقق لاغية وطرق فائدة. كانت عامة، ولكن إذا كنت تسميها لسبب ما، وانت تعرف ما المعلمات التي تمرر. هذا هو مثل محاولة لغلي الماء في غلاية دون توفير المياه ...

وأخيرا، في التعليمة البرمجية، السطر الأول من الأسلوب العام وغني عن مثل هذا:

ValidationUtils.getNullValidator().addParam(plans, "plans").addParam(persons, "persons").validate();

لاحظ أن addParam () إرجاع النفس، بحيث يمكنك إضافة المزيد من المعلمات للتحقق.

طريقة validate()سوف رمي فحص ValidationExceptionإذا كان أي من المعلمات لاغيا (محددة أو غير محددة هو أكثر قضية تصميم / الذوق، ولكن بلدي ValidationExceptionمحددا).

void validate() throws ValidationException;

سيحتوي الرسالة النص التالي إذا، على سبيل المثال، "خطط" فارغة:

" مصادفة غير القانوني لاغية قيمة وسيطة ل[الخطط] المعلمة "

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

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

بهذه الطريقة، رمز نظيفة وسهلة للصيانة وقابل للقراءة.




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

  1. السماح للاستثناءات تموج من خلال - القاء القبض عليهم في 'حلقة رئيسية "أو في بعض الروتين الإداري الآخرين.

    • تحقق من وجود حالات الخطأ والتعامل معها بشكل مناسب

تفعل بالتأكيد إلقاء نظرة على الجانب برمجة، وأيضا - لديهم طرق أنيق لادخال if( o == null ) handleNull()إلى بايت كود الخاص بك.




بالإضافة إلى استخدام assertيمكنك استخدام ما يلي:

if (someobject == null) {
    // Handle null here then move on.
}

هذا هو أفضل قليلا من:

if (someobject != null) {
    .....
    .....



    .....
}



فقط لا تستخدم أي وقت مضى لاغية. لا تسمح بذلك.

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

مرة واحدة اعتمدت هذه الممارسة، لاحظت أن المشاكل يبدو لإصلاح أنفسهم. وكنت التقاط الأشياء قبل ذلك بكثير في عملية التنمية فقط عن طريق الصدفة، وندرك كان لديك نقطة ضعف .. والأهم .. أنه يساعد تغليف وحدات مختلفة "المخاوف، وحدات مختلفة يمكن أن 'الثقة' بعضهم البعض، وليس أكثر من رمي النفايات في الرمز مع if = null elseثوابت!

هذا هو البرمجة الدفاعية والنتائج في التعليمات البرمجية أنظف بكثير على المدى الطويل. دائما تطهير البيانات، على سبيل المثال هنا من خلال فرض معايير صارمة، والمشاكل تذهب بعيدا.

class C {
    private final MyType mustBeSet;
    public C(MyType mything) {
       mustBeSet=Contract.notNull(mything);
    }
   private String name = "<unknown>";
   public void setName(String s) {
      name = Contract.notNull(s);
   }
}


class Contract {
    public static <T> T notNull(T t) { if (t == null) { throw new ContractException("argument must be non-null"); return t; }
}

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




الجوافة ومكتبة الأساسية مفيدة للغاية من قبل جوجل، لديها API جميل ومفيد لتجنب بالقيم الخالية. أجد UsingAndAvoidingNullExplained مفيدة جدا.

كما هو موضح في ويكي:

Optional<T>هو وسيلة لاستبدال T إشارة قيم الفارغة مع قيمة غير فارغة. والاختياري إما أن تحتوي على T إشارة غير فارغة (في هذه الحالة نقول المرجعية هي "الحالية")، أو أنها قد تحتوي على أي شيء (في هذه الحالة نقول الإشارة "غائبة"). ويقال أبدا "لاحتواء اغية".

الاستعمال:

Optional<Integer> possible = Optional.of(5);
possible.isPresent(); // returns true
possible.get(); // returns 5



أنا أحب المقالات من نات برايس. وهنا الروابط:

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




هذه مشكلة شائعة جدا لكل مطور جافا. حتى لا يكون هناك دعم رسمي في جاوة 8 لمعالجة هذه القضايا دون رمز تشوش.

وقد أدخلت جافا 8 java.util.Optional<T>. ومن حاوية قد تكون أو لا يحمل قيمة غير فارغة. وقد أعطى جافا 8 طريقة أكثر أمانا للتعامل مع كائن التي قد تكون لاغية في بعض الحالات القيمة. وهو مستوحى من أفكار هاسكل و سكالا .

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

في المثال أعلاه لدينا مصنع خدمة الوطن وترجع مؤشر إلى الأجهزة المتعددة المتوفرة في المنزل. ولكن هذه الخدمات قد أو قد لا تكون متوفرة / الوظيفية. وهذا يعني أنه قد يؤدي إلى NullPointerException. بدلا من إضافة فارغة ifحالة قبل استخدام أي خدمة، دعونا التفاف عليه في لاختياري <خدمة>.

الالتفاف إلى OPTION <T>

دعونا النظر في طريقة للحصول على إشارة من الخدمة من المصنع. بدلا من إرجاع إشارة الخدمة، ألفه مع الاختياري. وهو يتيح للمستخدم API يعرفون أن الخدمة عادت قد أو قد لا تتوفر / الوظيفية، واستخدام الدفاعي

public Optional<Service> getRefrigertorControl() {
      Service s = new  RefrigeratorService();
       //...
      return Optional.ofNullable(s);
   }

كما ترون Optional.ofNullable()يوفر وسيلة سهلة للحصول على إشارة ملفوفة. وهناك طرق أخرى للحصول على مرجع الاختياري، إما Optional.empty()و Optional.of(). واحدة للعودة كائن فارغ بدلا من إعادة ضبطها لاغية والآخر للالتفاف كائن غير قيم الفارغة، على التوالي.

فكيف بالضبط يساعد على تجنب NULL التحقق؟

وبمجرد الانتهاء من ملفوفة كائن مرجعية، يوفر الاختياري العديد من الأساليب المفيدة لاستدعاء الأساليب على إشارة ملفوفة دون NPE.

Optional ref = homeServices.getRefrigertorControl();
ref.ifPresent(HomeServices::switchItOn);

Optional.ifPresent استدعاء المستهلك معين مع الإشارة إذا كانت قيمة غير فارغة. وإلا، فإنه لا يفعل شيئا.

@FunctionalInterface
public interface Consumer<T>

يمثل العملية التي يقبل حجة مدخلات واحدة وإرجاع أية نتيجة. وخلافا لمعظم واجهات الفنية الأخرى، ومن المتوقع أن يعمل من خلال الآثار الجانبية المستهلك. وهي نظيفة جدا وسهلة الفهم. في المثال رمز أعلاه، HomeService.switchOn(Service)يحصل الاحتجاج إذا كانت الإشارة عقد الاختيارية هي غير خالية.

نحن نستخدم المشغل الثلاثي في ​​كثير من الأحيان لفحص حالة فارغة وإرجاع قيمة بديلة أو القيمة الافتراضية. الاختياري يوفر طريقة أخرى للتعامل مع حالة نفسه دون التحقق فارغة. Optional.orElse (defaultObj) إرجاع defaultObj إذا كان لدى الاختياري قيمة فارغة. دعونا نستخدم هذا في نموذج التعليمات البرمجية لدينا:

public static Optional<HomeServices> get() {
    service = Optional.of(service.orElse(new HomeServices()));
    return service;
}

الآن HomeServices.get () لا نفس الشيء، ولكن بطريقة أفضل. فإنه يتحقق ما إذا كانت تتم تهيئة الخدمة بالفعل لا. إذا كان ثم نعود لنفس أو إنشاء خدمة جديدة جديدة. اختياري <T> .orElse (T) يساعد على إرجاع القيمة الافتراضية.

وأخيرا، وهنا لدينا NPE وكذلك كود خالية من الاختيار لاغيا:

import java.util.Optional;
public class HomeServices {
    private static final int NOW = 0;
    private static Optional<HomeServices> service;

public static Optional<HomeServices> get() {
    service = Optional.of(service.orElse(new HomeServices()));
    return service;
}

public Optional<Service> getRefrigertorControl() {
    Service s = new  RefrigeratorService();
    //...
    return Optional.ofNullable(s);
}

public static void main(String[] args) {
    /* Get Home Services handle */
    Optional<HomeServices> homeServices = HomeServices.get();
    if(homeServices != null) {
        Optional<Service> refrigertorControl = homeServices.get().getRefrigertorControl();
        refrigertorControl.ifPresent(HomeServices::switchItOn);
    }
}

public static void switchItOn(Service s){
         //...
    }
}

وظيفة كاملة هي NPE وكذلك كود خالية من الاختيار لاغية ... حقا؟ .




لقد حاولت NullObjectPatternولكن بالنسبة لي ليس دائما أفضل وسيلة للذهاب. هناك في بعض الأحيان عندما يكون "أي إجراء" ليست appropiate.

NullPointerExceptionهو استثناء وقت التشغيل وهذا يعني أنه من المطورين لوم ومع ما يكفي من الخبرة يخبرك بالضبط أين هو الخطأ.

الآن إلى الإجابة:

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

وبطبيعة الحال، والخبرة هي أفضل وسيلة لفهم وتطبيق هذا الاقتراح.

بايت!




اسمحوا لي أن الإجابة على هذا السؤال بشكل عام!

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

لذلك ليس هناك فرق بين:

if(object == null){
   //you called my method badly!

}

أو

if(str.length() == 0){
   //you called my method badly again!
}

كلاهما يريد للتأكد من أن تلقينا المعلمات صالحة، قبل ان نفعل أي وظائف أخرى.

كما ذكر في بعض إجابات أخرى، لتجنب المشاكل المذكورة أعلاه يمكنك اتباع تصميم بموجب عقد النمط. يرجى الاطلاع http://en.wikipedia.org/wiki/Design_by_contract .

لتنفيذ هذا النمط في جافا، يمكنك استخدام شروح جافا الأساسية مثل javax.annotation.NotNull أو استخدام المكتبات أكثر تطورا مثل السبات المصادقة .

مجرد عينة:

getCustomerAccounts(@NotEmpty String customerId,@Size(min = 1) String accountType)

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

يمكنك الذهاب إلى أبعد من ذلك والتأكد من أن فقط pojos صالحة يمكن إنشاء في التطبيق الخاص بك. (عينة من موقع السبات مدقق)

public class Car {

   @NotNull
   private String manufacturer;

   @NotNull
   @Size(min = 2, max = 14)
   private String licensePlate;

   @Min(2)
   private int seatCount;

   // ...
}



  1. أبدا التهيئة المتغيرات فارغة.
  2. إذا (1) غير ممكن، التهيئة جميع المجموعات والمصفوفات لمجموعات فارغة / المصفوفات.

القيام بذلك في التعليمات البرمجية الخاصة بك ويمكنك تجنب! = شيكات فارغة.

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

// Bad
ArrayList<String> lemmings;
String[] names;

void checkLemmings() {
    if (lemmings != null) for(lemming: lemmings) {
        // do something
    }
}



// Good
ArrayList<String> lemmings = new ArrayList<String>();
String[] names = {};

void checkLemmings() {
    for(lemming: lemmings) {
        // do something
    }
}

هناك فوق صغير في هذا، ولكن الامر يستحق ذلك لرمز أنظف وأقل NullPointerExceptions.




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

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

كما نضع في اعتبارنا، أن نمط جوه لاغية سوف تكون الذاكرة جائع إذا ما استخدمت دون رعاية. لهذا - يجب أن تكون مشتركة مثيل NullObject بين أصحابها، وليس أن يكون مثيل unigue لكل من هذه.

كما أود أن لا نوصي باستخدام هذا النمط حيث يعني نوع لتكون بدائية نوع التمثيل - مثل الهيئات الرياضية، والتي ليست سكالارس: ناقلات، المصفوفات، والأرقام المعقدة وPOD الكائنات (عادي بيانات قديم)، والتي تهدف لعقد الدولة في شكل جافا المدمج في أنواع. في الحالة الأخيرة سوف ينتهي بك الأمر استدعاء الأساليب جالبة مع نتائج التعسفية. على سبيل المثال ما الذي يجب أن NullPerson.getName () طريقة العودة؟

ومن الجدير النظر في مثل هذه الحالات لتفادي نتائج غير معقولة.




هذا هو حدوث الخطأ الأكثر شيوعا لمعظم المطورين.

لدينا عدد من الطرق للتعامل مع هذا.

النهج 1:

org.apache.commons.lang.Validate //using apache framework

notNull (كائن كائن، رسالة سلسلة)

النهج 2:

if(someObject!=null){ // simply checking against null
}

النهج 3:

@isNull @Nullable  // using annotation based validation

النهج 4:

// by writing static method and calling it across whereever we needed to check the validation

static <T> T isNull(someObject e){  
   if(e == null){
      throw new NullPointerException();
   }
   return e;
}



ربما أفضل بديل لجاوا 8 أو أحدث لاستخدام Optionalالطبقة.

Optional stringToUse = Optional.of("optional is there");
stringToUse.ifPresent(System.out::println);

هذا هو مفيد خاصة لسلاسل طويلة من القيم الخالية الممكنة. مثال:

Optional<Integer> i = Optional.ofNullable(wsObject.getFoo())
    .map(f -> f.getBar())
    .map(b -> b.getBaz())
    .map(b -> b.getInt());

مثال على كيفية رمي استثناء على باطل:

Optional optionalCarNull = Optional.ofNullable(someNull);
optionalCarNull.orElseThrow(IllegalStateException::new);

قدم جافا 7 Objects.requireNonNullالطريقة التي يمكن أن تكون في متناول اليد عندما يجب أن يتم التحقق شيئا لغير nullness. مثال:

String lowerVal = Objects.requireNonNull(someVar, "input cannot be null or empty").toLowerCase();



public static <T> T ifNull(T toCheck, T ifNull) {
    if (toCheck == null) {
           return ifNull;
    }
    return toCheck;
}