تجنّب NullPointerExceptions
أنماط لكتابة شيفرة آمنة
تجنّب NullPointerExceptions درس مجاني في Android Academy على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Android Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Android Academy 4 دروس في المجموع.
الهدف: عدم حدوث NPEs
يحدث NullPointerException، أو NPE، عندما تستخدم التعليمات البرمجية شيئًا تكون قيمته الفعلية null. صُممت Kotlin لجعل حدوث ذلك نادرًا.
يجمع هذا الدرس الأدوات التي تعلمتها، ويحذرك من الطرق القليلة التي قد يتسلل بها NPE رغم ذلك.
المعامل !!
يخبر تأكيد عدم كون القيمة null، !!، المترجمَ بأن يثق في أن القيمة ليست null. وإذا كنت مخطئًا، فإنه يرمي NPE.
يلغي هذا المعامل الأمان، لذا استخدمه نادرًا وفقط عندما تكون متأكدًا.
fun main() {
val name: String? = "Ada"
println(name!!.length) // works, name is not null
}قد يتسبب !! في تعطل البرنامج
إذا كانت القيمة null فعلًا، فإن !! يرمي NullPointerException في ذلك السطر تحديدًا.
وهذه هي الطريقة الأساسية لإعادة المشكلة نفسها التي تمنعها Kotlin. تجنب !! عندما يكون بإمكانك استخدام الاستدعاء الآمن أو Elvis.
val name: String? = null
println(name!!.length)
// throws KotlinNullPointerExceptionفضّل البدائل الآمنة
يمكن إعادة كتابة أي استخدام تقريبًا لـ !! باستخدام ?. و?:. ولا يمكن للصيغة الآمنة أن تتسبب في تعطل البرنامج.
قارن بين الصيغتين الخطرة والآمنة أدناه.
// Risky:
val len1 = name!!.length
// Safe:
val len2 = name?.length ?: 0تحقق مبكرًا
عالج null عند حدود التعليمات البرمجية، ثم تعامل مع قيم غير null في الداخل. استخدم Elvis مع return أو throw لرفض الإدخال المفقود منذ البداية.
بعد عملية الحماية، تُحوَّل القيمة تلقائيًا إلى نوع غير قابل لـ null باستخدام smart cast.
fun length(s: String?): Int {
val text = s ?: return 0
return text.length
}requireNotNull
عندما تعني قيمة null وجود خطأ فعلًا، ترمي requireNotNull خطأً واضحًا وتُرجع القيمة غير القابلة لـ null.
وهي أكثر وصفًا من !!، لأنك تستطيع إضافة رسالة.
fun start(config: String?) {
val c = requireNotNull(config) { "config missing" }
println(c.length)
}الأنواع القادمة من Java
تكون للقيم القادمة من Java قابلية null غير معروفة، وتُسمى هذه القيم أنواع المنصة. ولا تستطيع Kotlin ضمان أنها غير null.
عند استخدام مكتبات Java، صرّح بالنوع المتوقع صراحةً وتعامل مع null بحذر.
// From Java: String maybe = obj.getName();
val name: String? = obj.name // be safe
println(name?.length ?: 0)مشكلة lateinit
يتيح لك lateinit var تأجيل تهيئة خاصية غير قابلة لـ null. لكن استخدامها قبل إسناد قيمة إليها يؤدي إلى رمي استثناء.
استخدم lateinit فقط عندما تكون متأكدًا من تعيين القيمة قبل أي وصول إليها.
lateinit var config: String
fun read() {
println(config.length)
// crashes if config was never set
}القيم الافتراضية بدلًا من null
غالبًا ما يمكنك تجنب قابلية null بالكامل باختيار قيمة افتراضية مناسبة. فكثيرًا ما تكون السلسلة النصية الفارغة أو القائمة الفارغة أفضل من null.
كلما قل عدد الأنواع التي تقبل null، قل احتمال حدوث NPE.
fun main() {
val tags: List<String> = emptyList()
println(tags.size) // 0, never null
}مسار معالجة آمن
يقرأ هذا البرنامج قيمة اختيارية، ويحوّلها بأمان، وينتج دائمًا نتيجة. لا يوجد !! ولا يحدث أي تعطل.
هذا هو الأسلوب الذي ينبغي أن تستهدفه في تعليمات Android البرمجية الفعلية.
fun main() {
val input: String? = null
val result = input?.trim()?.uppercase() ?: "N/A"
println(result) // prints: N/A
}أفضل الممارسات
فضّل الأنواع غير القابلة لـ null، وعالج null عند الحدود باستخدام Elvis، واستخدم ?.let للإجراءات الاختيارية. احتفظ بـ !! للحالات النادرة التي يستحيل فيها أن تكون القيمة null.
باتباع هذه العادات، تصبح NullPointerExceptions شيئًا من الماضي.
val safe = data?.value ?: default
data?.let { handle(it) }تحقق سريع
اختبر مدى فهمك لتجنب NullPointerExceptions.
مراجعة
تحدث NPEs في Kotlin عادةً بسبب !!، أو أنواع المنصة القادمة من Java، أو قيم lateinit غير المهيأة. تجنبها بتفضيل الأنواع غير القابلة لـ null والمعاملات الآمنة.
استخدم ?. و?: و?.let وعمليات التحقق مثل requireNotNull للحفاظ على تعليمات برمجية خالية من الأعطال. لقد أكملت الآن أساسيات أمان التعامل مع null في Kotlin.
تعلم Kotlin مع معلم ذكاء اصطناعي — مجانًا
اكتب وقم بتشغيل أكوادك الفعلية في المتصفح، واحصل على مساعدة فورية من معلم ذكاء اصطناعي متاح 24/7، واستمر من حيث توقفت على الويب أو في التطبيق.
- الدورات
- 36
- الدروس
- 152
الأسئلة الشائعة
هل درس «تجنّب NullPointerExceptions» مجاني؟
نعم — نص درس «تجنّب NullPointerExceptions» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Android Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Android Academy 4 دروس في المجموع.
ماذا ستتعلم في «تجنّب NullPointerExceptions»؟
أنماط لكتابة شيفرة آمنة تتمرن على Android Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Android Academy؟
لا تُشترط خبرة سابقة. Android Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.
كم من الوقت يستغرق درس «تجنّب NullPointerExceptions»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Android Academy هذا؟
نعم. كل درس في Android Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- الأنواع القابلة للقيمة الفارغة وغير القابلة لها
- الاستدعاءات الآمنة وElvis
- let وalso ودوال النطاق
- تجنّب NullPointerExceptions