خداحافظی با خطای Null Pointer در جاوا
خطای Null Pointer یکی از معروف ترین و رایج ترین خطاهای برنامه نویسی است. در این مقاله قصد داریم تا با این خطا خداحافظی کنیم. در ابتدا به بررسی این خطا میپردازیم.
Null
وقتی یک متغیر را تعریف میکنیم, در واقع یک اشارهگر را برای موقعیت آن ایجاد میکنیم. حتما برای شما پیش آمده است که متغیر هایی را از نوع int, double و چنین نوع هایی تعریف کرده باشید. چنین متغیر هایی از نوع primary type هستند. primary type ها با حروف کوچک نوشته و تعریف میشوند. کد زیر را در نظر بگیرید:
public static long id; public static void main(String[] args) { id = 2000; System.out.println(id); }
وقتی متغیر id را از نوع long تعریف میکنیم, به صورت پیش فرض مقدار صفر را به آن اختصاص میدهد. در واقع یک خانه از حافظه را مشخص میکند و مقدار صفر را در آن خانه قرار میدهد. سپس در مرحله بعد وقتی مقدار ۲۰۰۰ را به آن اختصاص میدهیم, مقدار ۲۰۰۰ را بجای صفر قرار میدهد. در واقع خانه حافظه ثابت است و مقدار آن تغییر میکند. اما گاهی متغیری را به صورت reference type تعریف میکنیم:
public static Long id; public static void main(String[] args) { System.out.println(id); }
Reference Type ها را با حروف بزرگ تعریف میکنیم. در این حالت متغیر ما مقدار اولیه ندارد. در این حالت مشخص نشده است که این متغیر به کدام یک از خانه های حافظه اشاره کند. به این ترتیب مقدار null به آن اختصاص داده میشود. وقتی از کلمه کلیدی new استفاده میکنیم, عملا یک بخشی از حافظه را به این متغیر اختصاص میدهیم. اکنون object به حالت قابل استفاده در میآید.
خطا Null Pointer
وقتی یک متغیر میسازیم ولی به آن مقداری را اختصاص نمیدهیم, در هنگام استفاده از آن, با چنین خطایی مواجه میشویم. در واقع وقتی یک خانه حافظه برای یک object در نظر گرفته نشود, نمیتوانیم از خواص آن مانند متد ها و متغیر های آن استفاده کنیم. در واقع وقتی میخواهیم از یک Object که مقداری به آن اختصاص ندادهایم استفاده کنیم, با خطای Null pointer مواجه میشویم:
public static Long id; public static void main(String[] args) { System.out.println(id.byteValue()); }
کد فوق با خطای Null pointer مواجه میشود و کد زیر بدون خطا اجرا میشود:
public static Long id; public static void main(String[] args) { id = new Long(2000); System.out.println(id.byteValue()); }
استفاده از Optional
Optional یک کلاس است که با استفاده از آن دیگر با خطای Null pointer مواجه نمیشویم. این کلاس در جاوا ۸ معرفی شدهاست. با استفاده از Optional, موجودیت یک مقدار را مشخص میکنیم. برای ایجاد Optional سه متد وجود دارد:
- Empty : یک Optional خالی را ایجاد میکند
- Of : یک ورودی دریافت میکند که همان متغیر مد نظر ما است. توجه داشته باشد که متغیر هایی که به آن ارجاع میدهیم نباید خاصیت Nullable را داشته باشد.
- OfNullable : مانند متد Of است با این تفاوت که برای متغیر های Nullable باید استفاده شوند. به این معنا که متغیر های ارسالی به این متد ممکن است Null باشند.
کد زیر را در نظر بگیرید, با استفاده از کد زیر مقداری را به Optional ارجاع میدهیم:
public class NullPoint { private static int nonNullable; public static void main(String[] args) { NullPoint nullPoint=new NullPoint(); Integer nullable = new Integer(2); Integer nullInteger = null; nullPoint.check(Optional.of(nonNullable)); nullPoint.check(Optional.ofNullable(nullable)); nullPoint.check(Optional.ofNullable(nullInteger)); } public void check(Optional<Integer> integer) { if (integer.isPresent()) { System.out.println("value : " + integer.get()); } else { System.out.println("No Value"); } } }
در کد فوق, سه متغیر تعریف کردهایم. با استفاده متد check, مقدار متغیر ها را مشخص میکنیم. در این متد, با استفاده از متد isPresent, مقدار متغیر بررسی میشود. اگر مقدار متغیر null نبود, آن را در خروجی چاپ میکند. اگر متغیر مقداری نداشته باشد, یک اخطار را به کاربر نمایش میدهد. خروجی کد فوق به صورت زیر است:
value : 0 value : 2 No Value
همانطور که در نتیجه مشخص است, با اینکه مقداری را برای nonNullable تعریف نکردهایم, اما میبینیم که مقدار آن برابر null نیست. این خاصیت متغیر های primary است.
گاهی میتوانیم مشخص کنیم که اگر مقدار متغیر null بود, یک مقدار دیگر را به عنوان مقدار متغیر در نظر بگیرد. این عمل را با استفاده از متد orElse انجام میدهیم:
nullPoint.elseUsag(Optional.of(nonNullable)); nullPoint.elseUsag(Optional.ofNullable(nullable)); nullPoint.elseUsag(Optional.ofNullable(nullInteger)); .... public void elseUsag(Optional<Integer> integer) { System.out.println("Value " + integer.orElse(new Random().nextInt(20))); }
در متد فوق, اگر متغیر مقداری نداشته باشد, یک عدد تصادفی را به عنوان مقدار آن در نظر میگیرد. همچنین متد filter, flatMap و map نیز در کلاس Optional وجود دارد که استفاده از آن مانند استفاده در Stream است.
در این مقاله سعی بر این شد تا با استفاده از کلاس Optional, از بروز خطای Null pointer جلوگیری کنیم.
با ما همراه باشید.
دیدگاهتان را بنویسید
برای نوشتن دیدگاه باید وارد بشوید.