سرفصل‌های آموزشی
آموزش جاوا
بررسی انواع ارورها در زبان برنامه‌نویسی جاوا

بررسی انواع ارورها در زبان برنامه‌نویسی جاوا

ارورها بخشی جدایی‌ناپذیر از فرآیند توسعۀ نرم‌افزار هستند به طوری که آشنایی با ‌انواع ارورها و تسلط بر چگونگی رفع آن‌ها از اهمیت بالایی برخوردار می‌باشد که در همین راستا در این آموزش قصد داریم تا با انواع ارورها در زبان برنامه‌نویسی جاوا آشنا شده و به بررسی نحوۀ رفع آن‌ها با به‌کارگیری قابلیت‌های محیط برنامه‌نویسی اکلیپس بپردازیم. به طور کلی، در زبان برنامه‌نویسی جاوا ارورها به چند دسته تقسیم می‌شوند که در ادامه هر یک را در قالب مثالی کاربردی بررسی می‌نماییم.

ارورهای Compile-time

گروه اول ارورهایی هستند که از نوع اصطلاحاً Compile-time می‌باشند. به طور مثال، دستور ;()system.out.println در مقایسه با دستور ;()System.out.println اشتباه است چرا که در آموزش‌های گذشته اشاره کردیم که زبان برنامه‌نویسی جاوا نسبت به بزرگ و کوچک بودن حروف حساس بوده و در این مثال نیز حرف اول از کیورد System به صورت کوچک نوشته شده است که همین مسئله منجر به بروز مشکل در فرآیند کامپایل برنامه می‌گردد. به علاوه، مجموعۀ ارورهای Compile-time از جمله ارورهایی هستند که توسط محیط‌های برنامه‌نویسی همچون نرم‌افزار اکلیپس تشخیص داده شده و به برنامه‌نویس اخطار داده می‌شوند که از همین روی به سادگی می‌توان آن‌ها را رفع نمود که جهت درک بهتر مطلب فوق چند مثال کاربردی را در ادامه مورد بررسی قرار می‌دهیم.

در ابتدا بر اساس آنچه که در آموزش‌های پیشین آموختیم، پروژه‌ای در محیط برنامه‌نویسی اکلیپس ایجاد کرده و یک کلاس با نام دلخواهی همچون CompileTimeErrors تعریف می‌کنیم (توجه داشته باشیم که نام کلاس می‌باید دقیقاً مشابه نام فایل ساخته‌شده در طی ایجاد پروژه با پسوند java. باشد که در غیر این صورت اجرای برنامه با مشکل مواجه خواهد شد.) و پس از ایجاد پروژه باید کدی مشابه زیر داشته باشیم:

public class CompileTimeErrors {
    /**
    * @param args
    */
    public static void main(String[] args) {
    // TODO Auto-generated method stub
    }
}

حال قصد داریم تا استرینگ «.This is a compile time error» را در کنسول نمایش دهیم که از همین روی نیاز است تا کد فوق را به شکل زیر تکمیل نماییم:

public class CompileTimeErrors {
    public static void main(String[] args) {
        System.out.println("This is a compile time error.");
    }
}

کد فوق یک برنامۀ کامل و صحیح در زبان برنامه‌نویسی جاوا است که بدون هیچ مشکلی اجرا می‌شود و لازم به یادآوری است که دستورهای کامنت‌شده را حذف نموده‌ایم چرا که هیچ تأثیری در نحوۀ اجرای برنامه نداشتند. حال در این مرحله قصد داریم تا عمداً تغییری در سورس‌کد ایجاد کنیم تا کامپایل برنامه منجر به بروز ارور شده و ببینیم که محیط برنامه‌نویسی اکلیپس چگونه ارور مربوطه را مشخص می‌سازد. برای این منظور، کیورد out که می‌باید حتماً با حروف کوچک نوشته شود را با حروف بزرگ و به صورت OUT می‌نویسیم که به محض تغییر واژۀ out به OUT و کامپایل مجدد سورس‌کد، آی‌دی‌ای اکلیپس دور واژۀ «OUT» یک خط‌چین قرار می‌دهد.

در واقع، در آی‌دی‌ای اکلیپس از روی دو مورد به راحتی می‌توان واژگانی را تشخیص داد که در حین کامپایل برنامه منجر به بروز ارور شده‌اند که عبارتند از:

  • مورد اول که در بالا بدان اشاره کردیم این است که آی‌دی‌ای اکلیپس کلمه‌ای که منجر به بروز ارور شده است را با خط‌چین مشخص می‌کند و با قرار دادن نشانگر ماوس خود روی واژۀ مشکل‌زا می‌توانیم متوجه اروری شویم که نرم‌افزار اکلیپس آن را شناسایی کرده است بدین صورت که پیامی مبنی بر علت بروز مشکل مربوطه قابل‌مشاهده می‌باشد که در این مثال با نگاه داشتن نشانگر ماوس روی واژۀ OUT شاهد پیغامی در قالب عبارت «OUT cannot be resolved or is not a field» خواهیم بود به علاوه اینکه آی‌دی‌ای اکلیپس یکسری پیشنهاد نیز به منظور رفع ارور مربوطه ارائه می‌دهد که برای مثال در مورد واژۀ OUT پیشنهاد تغییر آن به out را شاهد هستیم.
  • در مورد دوم نیز کنار نام فایل مربوط به پروژه که در اینجا CompileTimeError.java است، علامت هشداری مشاهده می‌شود که نشان‌دهندۀ وجود مشکلی در برنامه می‌باشد. 

مثال فوق، به منزلۀ یکی از ساده‌ترین انواع ارورها در زبان برنامه‌نویسی جاوا می‌باشد اما در عین حال ممکن است در طی کدنویسی با این زبان با یکسری اروری مواجه شویم که تا حدودی پیچیده‌تر هستند که در چنین شرایطی آی‌دی‌ای اکلیپس برای رفع مشکل ایجادشده بیش از یک مورد را پیشنهاد می‌دهد و در این صورت می‌باید تک‌تک پیشنهادات را مورد بررسی قرار داده سپس تغییر مورد نیاز را اِعمال کنیم تا در نهایت مشکل رفع گردد.

ارورهای Unchecked Runtime Exception

همچنین نوع دیگری از ارورها تحت عنوان Unchecked Runtime Exception شناخته می‌شوند که در صورت بروز چنین ارورهایی برنامه‌نویسان متوجه هیچ گونه اخطاری در سورس‌کد مبنی بر وجود مشکل در حین کامپایل برنامه نمی‌شوند اما این در حالی است که روند اجرای برنامه هم به صورت کامل انجام نمی‌شود که در چنین شرایطی می‌توان گفت که کامپایلر جاوا توان اجرای دستورات نوشته‌شده در سورس‌کد را ندارد.

به طور مثال، فرض کنیم که یک متغیر از جنس int یا عدد صحیح داریم که مقدار اختصاص داده‌شده به آن معادل 1،000،000 است که در این صورت در حین نوشتن برنامه با هیچ گونه مشکلی مواجه نخواهیم شد اما به محض کامپایل سورس‌کد با ارور مواجه خواهیم شد. در حقیقت، اِشکال کار مربوط به قرار دادن علامت کاما مابین ارقام عدد است و از همین روی کامپایلر جاوا قادر بر کامپایل برنامه نخواهد بود که به منظور رفع این مشکل می‌باید عدد فوق را به شکل 1000000 تغییر دهیم. به طور کلی، لازم به یادآوری است که نرم‌افزار اکلیپس توانایی تشخیص چنین مشکلاتی که ممکن است موجب ایجاد مشکل در حین کامپایل برنامه شوند را ندارد.

    به خاطر داشته باشید
ارورهای ایجادشده در برنامه‌نویسی اصطلاحاً Bug نامیده می‌شوند که به فرآیند مشکل‌یابی و رفع آن‌ها نیز Debugging گفته می‌شود و تسلط به نحوۀ دیباگ کردن ارورهای اپلیکیشن از جمله مهارت‌هایی است که هر برنامه‌نویسی می‌باید از آن برخوردار باشد. 

برای روشن‌تر شدن مسئلۀ فوق مثالی از دنیای واقعی می‌زنیم که در آن آدرس مکانی را از شخصی سؤال می‌کنیم و پاسخی بدین صورت دریافت می‌کنیم که می‌باید مستقیم برویم تا به یک چهارراه رسیده سپس به سمت راست حرکت کنیم که در این مرحله به سینمایی در خیابان روبه‌روی خود خواهیم رسید. حال فرض می‌کنیم که مسیر پیش روی خود را طبق آدرس داده‌شده طی کنیم و در نهایت به جای مشاهدۀ سینمایی در خیابان روبه‌روی خود به یک دیوار سیمانی برسیم! در چنین شرایطی ما در ابتدا از نادرست بودن آدرس مذکور اطلاع نداشتیم بلکه با طی مسیر متوجه آن شدیم که در مورد بروز ارورهای به اصطلاح Unchecked Runtime Exception نیز قضیه به همین شکل است به طوری که از بدو امر کامپایلر جاوا از وجود مشکل در برنامه ناآگاه بوده و نمی‌تواند بروز خطا در حین کامپایل برنامه را پیش‌بینی کند.

ارورهای Logical

دستۀ دیگرِ ارورها به اصطلاح Logical یا «منطقی» هستند که در صورت بروز چنین ارورهایی نرم‌افزار اکلیپس هیچ گونه خطایی را در معرض دید برنامه‌نویس قرار نمی‌دهد و برنامه هم به طور کامل اجرا می‌شود اما این در حالی است که پاسخ دریافت‌شده در نتیجۀ اجرای سورس‌کد صحیح نمی‌باشد. به منظور درک بهتر این موضوع به مثال فوق باز می‌گردیم که در آن آدرس داده‌شده بدین صورت است که به جای حرکت به سمت راست باید به سمت چپ برویم!

در واقع، ارورهای منطقی جزو چالش‌برانگیزترین ارورهای موجود در برنامه‌نویسی می‌باشند و بالتبع رفع آن‌ها نیز در مقایسه با سایر ارورها دشوارتر است مضاف بر اینکه برنامه‌نویسان در اکثر مواقع متوجه ارورهای منطقی برنامه نمی‌شوند که در آینده و با پیشرفت توسعۀ نرم‌افزار مد نظر مشکلات فراوانی را برای ایشان به وجود می‌آورند. برای درک بهتر ماهیت ارورهای منطقی در زبان جاوا و به عنوان یک مثال ساده از این دست ارورها، کد زیر را مد نظر قرار می‌دهیم:

public class HelloWorld {
    public static void main(String[] args) {
        int numA = 4;
        int numB = 20;
        System.out.println("The sum is " + numA + numB);
    }
}

در کد فوق، دو متغیر از جنس int یا عدد صحیح تحت عناوین numA و numB تعریف کرده و به ترتیب اعداد 4 و 20 را به هر یک اختصاص داده‌ایم و در دستور سطر پنجم نیز گفته‌ایم مقدار حاصل از جمع دو عدد منتسب به هر یک از دو متغیر مذکور را با استرینگ «The sum is» کانکت کرده و در کنسول چاپ کند. حال کد فوق را اجرا می‌کنیم که خروجی حاصل از آن به صورت زیر می‌باشد:

The sum is 420

در واقع، نتیجۀ حاصل از اجرای کد فوق با نتیجۀ مورد انتظار از آن متفاوت است و در چنین شرایطی می‌توان گفت که سورس‌کد مد نظر دارای ارور منطقی می‌باشد. در توضیح علت بروز چنین خطایی باید گفت که در زبان برنامه‌نویسی جاوا چنانچه بخواهیم مقادیری از جنس عدد صحیح و استرینگ را با به‌کارگیری عملگر + جمع کنیم، مقدارهای عددی به صورت خودکار از جنس استرینگ شناسایی شده و با سایر استرینگ‌ها کانکت می‌شوند و بدین ترتیب اعداد منتسب به دو متغیر numA و numB در قالب دو مقدار از جنس استرینگ با استرینگ «The sum is» کانکت می‌شوند (در آموزش‌های آتی با انواع عملگرها و نحوۀ به‌کارگیری آن‌ها در زبان برنامه‌نویسی جاوا آشنا می‌شویم.)

حال به منظور رفع چنین اروری در برنامۀ فوق، دستور numA + numB را داخل علائم () قرار می‌دهیم که در این صورت مفسر جاوا با رسیدن به سطر پنجم ابتدا محاسبات مربوط به دستورات داخل علائم () را انجام می‌دهد و بدین ترتیب دو مقدار از جنس عدد را با یکدیگر جمع کرده و در ادامه مقدار حاصل را با استرینگ «The sum is» کانکت کرده و در کنسول چاپ می‌کند که برای این منظور نیاز است تا کد فوق را به صورت زیر تغییر دهیم:

public class HelloWorld {
    public static void main(String[] args) {
        int numA = 4;
        int numB = 20;
        System.out.println("The sum is " + (numA + numB));
    }
}

همان‌طور که پیش‌تر اشاره کردیم، در سطر پنجم ابتدا دستور  numA + numB اجرا شده و دو عدد 4 و 20 با یکدیگر جمع می‌شوند و در ادامه مقدار حاصل از جمع آن‌ها که معادل عدد 24 است با استرینگ «The sum is» کانکت می‌‌شود که بدین ترتیب خروجی زیر در کنسول نمایش داده می‌شود:

The sum is 24

همچنین می‌توانیم به صورت جداگانه مقدار حاصل از جمع دو عدد را محاسبه کرده و آن را به متغیری اختصاص دهیم سپس متغیر مذکور را به عنوان آرگومان ورودی به متد ()println از دستور ;()System.out.println بدهیم که برای این منظور کدی مانند زیر خواهیم داشت:

public class HelloWorld {
    public static void main(String[] args) {
        int numA = 4;
        int numB = 20;
        int total = numA + numB;
        System.out.println("The sum is " + total);
    }
}

همان‌طور که ملاحظه می‌شود، متغیری از جنس int تحت عنوان total تعریف کرده و مقدار حاصل از جمع اعداد منتسب به دو متغیر numA و numB را به آن اختصاص داده‌ایم و بدین ترتیب دو عدد با هم جمع شده و در سطر پنجم نیز با استرینگ مربوطه کانکت شده و در کنسول نمایش داده می‌شوند که خروجی حاصل از اجرای کد فوق نیز مشابه مثال پیشین می‌باشد.

هشدارهای Compile-time

در نهایت هم هشدارها را داریم که تحت عنوان Compile-time Warning شناخته می‌شوند. به طور کلی، اهمیت این دسته از هشدارها به اندازۀ ارورها نبوده و زمانی رخ می‌دهند که محیط برنامه‌نویسی اکلیپس مسئله‌ای مشکوک را در سورس‌کد شناسایی کند و بدین ترتیب سطری از کد را با آیکانی به رنگ زرد با علامت تعجب مشخص می‌سازد که احتمالاً در آینده موجب ایجاد مشکل در طی توسعۀ اپلیکیشن خواهد شد.

در همین راستا، مثالی را مد نظر قرار می‌دهیم که در آن یک متغیر از جنس عدد صحیح یا int تحت عنوان test تعریف کرده و مقداری معادل با عدد 100 را بدان اختصاص داده‌ایم. حال چنانچه نرم‌افزار اکلیپس سطر مربوط به تعریف متغیر test را با علامت زرد مشخص کند، این بدان معنا است که متغیر مذکور در هیچ نقطه‌ای از برنامه مورد استفاده قرار نگرفته است. همچنین می‌توان نشانگر ماوس خود را روی علامت زرد رنگ نگاه داشته و پیشنهاد نرم‌افزار به منظور رفع هشدار را مشاهده کرد که در این مثال پیامی در قالب عبارت «The value of the local variable test is not used» نمایش داده خواهد شد.

online-support-icon