معرفی زبان برنامه نویسی جاوا – Java
معرفی زبان برنامه نویسی جاوا – Java
زبان برنامه نویسی جاوا ( زبان برنامه نویسی Java ) یک زبان برنامه نویسی همه منظوره است که همزمان، مبتنی بر کلاس و شیء گرا است و طوری طراحی شده است تا کمترین وابستگی اجرایی ممکن را داشته باشد. شعار این زبان، “یک بار بنویس، همه جا اجرا کن” است، یعنی کد جاوای کامپایل شده می تواند روی تمام پلتفرم هایی که از جاوا پشتیبانی می کنند، اجرا شود و نیازی به کامپایل کردن مجدد نیست. برنامه های جاوا معمولا به صورت Bytecode کامپایل می شوند و صرف نظر از ساختار کامپیوتر، می توانند روی هرگونه دستگاه مجازی اجرا شوند. در سال 2016، جاوا یکی از محبوب ترین زبان های برنامه نویسی مورد استفاده، مخصوصا برای برنامه های وب سرور مشتری است و گزارش شده است که 9 میلیون توسعه دهنده دارد. جاوا در ابتدا توسط جیمز گاسلینگ در شرکت Sun Microsystems توسعه یافت (که اکنون توسط شرکت Oracle خریداری شده است) و در سال 1995 به عنوان یک مولفه اصلی از پلتفرم جاوای شرکت Sun Microsystems عرضه شد. بیشتر قواعد این زبان از زبان های C و C++ گرفته شده است، اما امکانات سطح پایین کمتری نسبت به آنها دارد.
لوگوی شرکت Sun Microsystems
اجرای اصلی و مرجعی کامپایلرهای جاوا، ماشین های مجازی و کتابخانه های کلاس، در ابتدا توسط شرکت Sun تحت مجوزهای اختصاصی عرضه شدند. از می سال 2007، شرکت Sun، مطابق با ملزومات فرایند Java Community، بیشتر تکنولوژی های جاوای خود را تحت مجوز عمومی کلی گنو (GNU General Public) عرضه کرد. دیگران هم اجراهای دیگری از این تکنولوژی های شرکت Sun را توسعه داده اند، مانند کامپایلر گنو برای جاوا (کامپایلر Bytecode)، GNU Classpath (کتابخانه های استاندارد) و IcedTea-Web (پلاگین مرورگر برای Applet ها).
آخرین ورژن زبان برنامه نویسی جاوا، جاوای 8 است که تنها ورژنی است که در حال حاضر به صورت رایگان توسط Oracle پشتیبانی می شود، گرچه ورژن های قدیمی تر توسط Oracle و دیگر شرکت ها به صورت تجاری پشتیبانی می شوند.
تاریخچه زبان برنامه نویسی Java
جیمز گاسلینگ، مایک شریدان و پاتریک ناتون، در ژوئن سال 1991، پروژه زبان برنامه نویسی جاوا را آغاز کردند. زبان برنامه نویسی جاوا در ابتدا برای تلویزیون تعاملی طراحی شده بود، اما برای صنعت تلویزیون کابلی دیجیتال آن زمان بسیار پیشرفته بود. این زبان در ابتدا Oak (بلوط) نام داشت که برگرفته شده از درخت بلوطی بود که بیرون از دفتر گاسلینگ قرار داشت. بعدا این پروژه Green نام گرفت و در نهایت نام آن به Java تغییر یافت که برگرفته از قهوه جاوه است. گاسلینگ زبان برنامه نویسی جاوا را با قاعده نحوی سبک C و C++ طراحی کرد که برنامه نویس های سیستم و برنامه با آن آشنایی دارند.
شرکت Sun Microsystems اولین اجرای عمومی زبان برنامه نویسی جاوا را به عنوان java 1.0 در سال 1995 عرضه کرد. شعار آن “یک بار بنویس، همه جا اجرا کن” بود و اجرای بدون هزینه روی پلتفرم های محبوب را فراهم می کرد. این زبان که بسیار ایمن بوده و ایمنی آن قابل پیکربندی بود، اجازه محدود کردن دسترسی به شبکه و فایل ها را می داد. مرورگرهای بزرگ وب به زودی قابلیت اجرای Applet های جاوا در صفحات وب را اضافه کردند و زبان برنامه نویسی جاوا به سرعت محبوب شد و این محبوبیت بیشتر در خارج از مرورگرها بود که این برنامه اولیه نبود. در ژانویه سال 2016، شرکت Oracle اعلام کرد که محیط های Runtime جاوای مبتنی بر JDK 9 دیگر پلاگین مرورگر را ادامه نخواهند داد. کامپایلر Java 1.0 توسط آرتور ون هاف در جاوا بازنویسی شد تا دقیقا با ملزومات زبان برنامه نویسی Java 1.0 مطابقت داشته باشد. با ظهور زبان برنامه نویسی Java 2 (که در ابتدا با نام J2SE 1.2 در دسامبر 1998 – 1999 عرضه شده بود)، ورژن های جدید دارای پیکربندی های مختلفی بودند که برای پلتفرم های مختلف ساخته شده بودند. J2EE شامل تکنولوژی ها و API هایی برای کاربردهای سازمانی بود که عموما در محیط های سرور اجرا می شوند، درحالیکه J2ME شامل API هایی بود که برای برنامه های موبایل بهینه شده بودند. ورژن دسکتاپ به J2SE تغییر نام داده شد. در سال 2006، شرکت Sun به خاطر اهداف بازاریابی، ورژن های جدید J2 را به ترتیب Java EE، Java ME و Java SE نامید.
در سال 1997، شرکت Sun Microsystems برای رسمی کردن زبان برنامه نویسی جاوا، به استانداردهای ISO/IEC JTC 1 و Ecma International روی آورد، اما به زودی از این کار صرف نظر کرد. جاوا یک استاندارد عمومی باقی مانده است که از طریق فرایند Java Community کنترل می شود. در یک برهه زمانی، شرکت Sun صرف نظر از اختصاصی بودن زبان برنامه نویسی جاوا، تمام اجراهای جاوا را بدون هزینه در دسترس قرار داد. شرکت Sun درآمدهای جاوای خود را از طریق فروش مجوز برای محصولات خاص مانند Java Enterprise System کسب می کرد.
در 13 نوامبر سال 2006، شرکت Sun بیشتر قسمت های ماشین مجازی جاوا (JVM) را به عنوان نرم افزار رایگان و کد باز تحت شرایط مجوز عمومی کلی گنو عرضه کرد. در 8 می سال 2007، شرکت Sun این فرایند را کامل کرد و تمام کدهای هسته ای JVM را تحت شرایط توزیع رایگان و کد باز در دسترس قرار داد، به جز بخش کوچکی از کدها که کپی رایت آنها متعلق به شرکت Sun نبود.
ریچ گرین، نایب رئیس شرکت Sun اعلام کرد که نقش شرکت Sun در رابطه با زبان برنامه نویسی جاوا مانند یک مُبلغ است. پس از خرید شرکت Sun Microsystems توسط شرکت Oracle در سال 2009 – 2010، Oracle خود را “ناظر تکنولوژی جاوا با تعهدی برای پرورش یک جامعه مشارکتی شفاف” توصیف کرد. علیرغم این موضوع، شرکت Oracle از Google به خاطر استفاده از جاوا در Android SDK شکایت کرد (به بخش Google در پایین مراجعه کنید). نرم افزار جاوا روی تمام دستگاه ها از لپتاپ ها گرفته تا مراکز داده، کنسول های بازی و ابرکامپیوترهای علمی اجرا می شود. در 2 آوریل سال 2010، جیمز گاسلینگ از شرکت Oracle استعفا داد.
اصول اولیه زبان برنامه نویسی Java
پنج هدف اصلی در ساخت زبان برنامه نویسی Java وجود داشت:
1. باید “ساده، شیء گرا و آشنا” باشد.
2. باید “قدرتمند و ایمن” باشد.
3. باید “از نظر ساختاری خنثی و قابل حمل” باشد.
4. باید با “عملکرد بالایی” اجرا شود.
5. باید “تفسیر شده، رشته ای و پویا” باشد.
ورژن های زبان برنامه نویسی جاوا
از سال 2015، تنها جاوای 8 (به صورت عمومی) پشتیبانی می شود. ورژن های عرضه شده اصلی زبان برنامه نویسی جاوا به همراه تاریخ عرضه شان در زیر آمده است:
JDK 1.0 (21 ژانویه 1996)
JDK 1.1 (19 فوریه 1997)
J2SE 1.2 (8 دسامبر 1998)
J2SE 1.3 (8 می 2000)
J2SE 1.4 (6 فوریه 2002)
J2SE 5.0 (30 سپتامبر 2004)
Java SE 6 (11 دسامبر 2006)
Java SE 7 (38 جولای 2011)
Java SE 8 (18 مارس 2014)
کاربردهای زبان برنامه نویسی Java
پلتفرم جاوا
یکی از اهداف طراحی زبان برنامه نویسی جاوا، قابلیت حمل است، یعنی برنامه هایی که برای پلتفرم جاوا نوشته شده اند باید روی هر ترکیبی از سخت افزار و سیستم عامل با پشتیبانی کافی از Runtime، اجرا شود. برای این کار، به جای کامپایل کردن مستقیم به کد ماشینی ساختار محور، کد زبان برنامه نویسی جاوا در یک واسطه به نام Java Bytecode کامپایل شد. دستوالعمل های Java Bytecode مشابه با کد ماشینی هستند، اما آنها توسط یک ماشین مجازی (VM) اجرا می شوند که مخصوص سخت افزار میزبان نوشته شده است. کاربران نهایی معمولا از یک محیط Java Runtime (JRE) استفاده می کنند که برای برنامه های جاوای انفرادی یا مرورگرهای وب برای Applet های جاوا، روی دستگاه هایشان نصب شده است.
کتابخانه های استاندارد یک روش عمومی برای دسترسی به ویژگی های مخصوص میزبان مانند گرافیک، threading و شبکه فراهم می کنند.
استفاده از Bytecode همگانی، انتقال آن را آسان می کند. هرچند، تفسیر Bytecode به دستورالعمل های ماشین، باعث می شود تا برنامه های تفسیر شده همیشه آهسته تر از برنامه های اجرایی محلی باشند. البته کامپایلرهای به هنگام یا Just in Time (JIT) از مراحل اولیه معرفی شدند که در زمان اجرا، بایت کدها را به کد ماشینی کامپایل می کنند. خود جاوا مستقل از پلتفرم است و توسط یک ماشین مجازی جاوا (JVM) با پلتفرمی که باید روی آن اجرا شود، سازگار می شود که Java Bytecode را به زبان ماشینی پلتفرم تفسیر می کند.
پیاده سازی ها
شرکت Oracle پس از خرید شرکت Sun Microsystems در 27 ژانویه سال 2007، صاحب کنونی پیاده سازی رسمی پلتفرم Java SE است. این پیاده سازی براساس پیاده سازی اصلی زبان برنامه نویسی جاوا توسط شرکت Sun است. پیاده سازی Oracle برای Microsoft Windows (هنوز برای XP کار می کند، البته تنها ورژن های بعدی به صورت عمومی پشتیبانی می شوند)، Mac OS X، Linux و Solaris موجود است. به دلیل اینکه زبان برنامه نویسی جاوا هیچ استاندارد رسمی ندارد که از طرف Ecma International، ISO/IEC، ANSI یا سازمان های استاندارد ثالث به رسمیت شناخته شود، پیده سازی Oracle یک استاندارد همگانی است.
پیاده سازی Oracle در دو نوع توزیع مختلف بسته بندی شده است: محیط Java Runtime (JRE) که حاوی قسمت هایی از پلتفرم Java SE است، برای اجرای برنامه های جاوا مورد نیاز است و برای کاربران نهایی طراحی شده است و بسته توسعه جاوا (JDK) که برای توسعه دهندگان نرم افزاری در نظر گرفته شده است، حاوی ابزارهای توسعه ای مانند Java Compiler، Javadoc، Jar و Debugger است.
ساختمان های مرکزی شرکت Oracle در ساحل ردوود کالیفرنیا
OpenJDK هم یک پیاده سازی قابل توجه دیگری است که دارای لیسانس GNU GPL است. این پیاده سازی زمانی آغاز شد که شرکت SUN شروع به عرضه کد منبع جاوا تحت محجوز GPL کرد. از Java SE 7 به بعد، OpenJDK، پیاده سازی مرجعی رسمی جاوا است.
هدف زبان برنامه نویسی جاوا این است که تمام پیاده سازی های جاوا، سازگار باشند. در گذشته، مجوز علامت تجاری Sun برای استفاده از برند جاوا نشان می دهد که تمام پیاده سازی ها باید سازگار باشند. این امر منجر به یک دعوی حقوقی با شرکت مایکروسافت شد و شرکت Sun اظهار کرد که پیاده سازی مایکروسافت از RMI یا JNI پشتیبانی نمی کند و ویژگی های خاص پلتفرم خود را اضافه کرده اند. شرکت Sun در سال 1997 شکایت کرد و در سال 2001 مبلغ 20 میلیون دلار غرامت گرفت و همچنین یک حکم دادگاهی شرایط مجوز را از طرف شرکت Sun اجرا کرد. در نتیجه مایکروسافت دیگر جاوا را به همراه ویندوز عرضه نمی کند.
جاوای مستقل از پلتفرم برای Java EE ضروری است و یک تایید اعتبار سخت تری برای تصدیق گواهی یک پیاده سازی مورد نیاز است. این محیط اجازه برنامه های سمت سرور قابل حمل را ممکن می سازد.
عملکرد
برنامه هایی که با زبان برنامه نویسی جاوا نوشته شده اند به این شهرت دارند که آهسته تر هستند و به حافظه بیشتری نسبت به برنامه های نوشته شده در زبان C++ نیاز دارند. هرچند، با معرفی فرایند کامپایل سازی Just in Time در سال های 1997 و 1998 برای Java 1.1، اضافه شدن ویژگی های زبان با پشتیبانی بهتر از تحلیل کد (مانند کلاس های داخلی، کلاس StripBuilder، assertion های اختیاری و غیره) و بهینه سازی ماشین مجازی جاوا، مانند پیش فرض شدن HotSpot در JVM در سال 2000، سرعت اجرای برنامه های جاوا بطور چشمگیری بهبود یافت. در Java 1.5 با اضافه شدن بسته java.util.concurrent که شامل پیاده سازی بدون قفل ConcurrentMaps و دیگر مجموعه های چند هسته ای، عملکرد آن بهبود پیدا کرد و در جاوای 1.6 بیشتر بهبود یافت.
برخی پلتفرم ها پشتیبانی سخت افزاری مستقیم برای جاوا ارائه می دهند. میکروکنترلرهایی وجود دارند که می توانند به جای نرم افزار، جاوا را در ماشین مجازی جاوای سخت افزاری اجرا کنند و پردازنده های مبتنی بر ARM می توانند پشتیبانی سخت افزاری برای اجرای Java Bytecode از طریق گزینه Jazelle داشته باشند (در نسخه های جدیدتر ARM، بیشتر این پشتیبانی متوقف شده است).
مدیریت حافظه خودکار
زبان برنامه نویسی جاوا از یک garbage collector خودکار استفاده می کند تا حافظه را در طول عمر شیء مدیریت کند. برنامه نویس تعیین می کند چه زمانی اشیا ساخته می شوند و زمانی که اشیا دیگر مورد استفاده قرار نگیرند، Java Runtime مسئولیت بازیابی حافظه را بر عهده دارد. زمانی که هیچ منبعی به شیء باقی نماند، حافظه غیر قابل دسترسی واجد شرایط آزاد شدن بطور خودکار توسط Garbage Collector می شود. البته اگر کد برنامه نویس به یک شیء رفرنس داشته باشد که دیگر مورد نیاز نیست، ممکن است چیزی شبیه نشت حافظه رخ دهد. این اتفاق معمولا زمانی می افتد که اشیایی که دیگر نیازی به آنها نیست در محفظه هایی ذخیره می شوند که هنوز در حال استفاده هستند. اگر متدهای یک شیء ناموجود فراخوانی شوند، خطای null pointer exception نمایش داده می شود.
یکی از ایده های پشت مدل مدیریت حافظه خودکار جاوا این است که نیازی نیست برنامه نویس ها مدیریت حافظه را به صورت دستی انجام دهند. در برخی زبان ها، حافظه برای ساخت اشیا بطور ضمنی روی Stack اختصاص داده می شود یا بوضوح از روی Heap اختصاص داده می شود و سپس گرفته می شود. در مورد دوم، مسئولیت مدیریت حافظه با برنامه نویس است. اگر برنامه یک شیء را deallocate نکند، نشت حافظه رخ می دهد. اگر برنامه سعی کند به یه حافظه ای که از قبل deallocate شده است دسترسی پیدا کند یا آن را deallocate کند، نتیجه نامشخص و پیش بینی آن است و برنامه احتمالا ناپایدار شده یا متوقف می شود. با استاده از Smart Pointer ها می توان این مشکل را تا حدی رفع کرد، اما اینها نیز فشار و پیچیدگی بیشتر ایجاد می کنند. توجه کنید که عمل Garbage Collection از نشت های حافظه ” منطقی” جلوگیری نمی کند، یعنی آنهایی که به حافظه هنوز رفرنس داده شده است، اما هرگز استفاده نمی شود.
Garbage Collection ممکن است در هر زمانی رخ دهد. بطور ایده آل باید زمانی اتفاق بیفتد که برنامه بیکار است. اگر حافظه آزاد کافی در Heap برای تخصیص دادن به یک شیء جدید وجود نداشته باشد، فعال شدن آن تضمین می شود. این کار می تواند باعث شود برنامه موقتا بی حرکت شود. مدیریت حافظه صریح در زبان برنامه نویسی جاوا امکان پذیر نیست.
زبان برنامه نویسی جاوا از pointer arithmetic سبک C و C++ که آدرس ها و اعداد صحیح تخصیص داده نشده (معمولا اعداد صحیح بلند) را می توان به جای هم استفاده کرد، پشتیبانی نمی کند. این امر به Garbage Collector اجازه می دهد تا اشیای ارجاع داده شده را از نو تخصیص دهند و از Type Safety و امنیت آن اطمینان حاصل کنند.
مانند C++ و دیگر زبان های شیء گرا، متغیرهای انواع داده های اولیه جاوا یا مستقیما در فیلدها (برای اشیا) ذخیره می شوند، یا روی Stack (برای متدها) به جای Heap، مانند انوع داده غیر اولیه. این یک تصمیم آگاهانه از طرف طراح زبان برنامه نویسی جاوا به خاطر مسائل عملکردی بود.
زبان برنامه نویسی جاوا حاوی چند نوع Garbage Collector است. بطور پیش فرض، HotSpot از parallel scavenge garbage collector استفاده می کند. البته چند Garbage Collector دیگر وجود دارد که برای مدیریت حافظه Heap می توانند مورد استفاده قرار گیرند. برای 90 درصد برنامه های جاوا، Concurrent Mark-Sweep (CMS) کفایت می کند. شرکت Oracle قصد دارد CMS را با Garbage-First collector (G1) جایگزین کند.
قاعده نحوی
قاعده نحوی زبان برنامه نویسی جاوا تا حد زیادی تحت تاثیر C++ بوده است. برخلاف زبان C++ که قاعده برنامه نویسی ساختاری، عمومی و شیء گرا را ترکیب می کند، زبان برنامه نویسی جاوا منحصرا به عنوان یک زبان شیء گرا ساخته شده است. تمام کدها در داخل کلاس ها نوشته می شوند و هر آیتم داده ای، یک شیء است، البته به استثنای انواع داده اولیه مانند اعداد صحیح، اعداد با ممیز شناور، مقادیر بولی و حروف که به دلایل عملکردی، جزو اشیا نیستند. زبان برنامه نویسی جاوا از برخی جنبه های محبوب C++ مجددا استفاده کرده است (مانند متد Printf()).
زبان برنامه نویسی جاوا برخلاف C++ از سربارگزاری عملگرها یا وراثت چندگانه برای کلاس ها پشتیبانی نمی کند، اما وراثت چندگانه برای رابط های کاربری پشتیبانی می شود. این کار منجر به سادگی زبان می شود و در جلوگیری از خطاهای احتمالی و طراحی ضد الگو، کمک می کند.
زبان برنامه نویسی جاوا از کامنت هایی مشابه C++ استفاده می کند. سه سبک مختلف از کامنت ها وجود دارد: سبک تک خطی که با دو تا اسلش (//) مشخص می شود، سبک چند خطی که با /* باز می شود و با */ بسته می شود و سبک کامنت گذاری Javadoc که با /** باز شده و با */ بسته می شود. سبک کامنت گذاری Javadoc به کاربر اجازه می دهد تا فایل اجرایی Javadoc را اجرا کند تا برای برنامه، سندسازی کند.
مثال:
// This is an example of a single line comment using two slashes /* This is an example of a multiple line comment using the slash and asterisk. This type of comment can be used to hold a lot of information or deactivate code, but it is very important to remember to close the comment. */ package fibsandlies; import java.util.HashMap; /** * This is an example of a Javadoc comment; Javadoc can compile documentation * from this text. Javadoc comments must immediately precede the class, method, or field being documented. */ public class FibCalculator extends Fibonacci implements Calculator { private static Map<Integer, Integer> memoized = new HashMap<Integer, Integer>(); /* * The main method written as follows is used by the JVM as a starting point for the program. */ public static void main(String[] args) { memoized.put(1, 1); memoized.put(2, 1); System.out.println(fibonacci(12)); //Get the 12th Fibonacci number and print to console } /** * An example of a method written in Java, wrapped in a class. * Given a non-negative number FIBINDEX, returns * the Nth Fibonacci number, where N equals FIBINDEX. * @param fibIndex The index of the Fibonacci number * @return The Fibonacci number */ public static int fibonacci(int fibIndex) { if (memoized.containsKey(fibIndex)) { return memoized.get(fibIndex); } else { int answer = fibonacci(fibIndex - 1) + fibonacci(fibIndex - 2); memoized.put(fibIndex, answer); return answer; } } }
نمونه ها
برنامه “Hello World!”
برنامه سنتی “Hello World!” را می توان در زبان برنامه نویسی جاوا به شکل زیر نوشت:
class HelloWorldApp { public static void main(String[] args) { System.out.println("Hello World!"); // Prints the string to the console. } }
فایل های منبع باید با کلاس عمومی که دارند هم نام باشند و پسوند .java بگیرند، مثلا HelloWorldApp.java. اول باید با استفاده از یک Java Compiler به bytecode کامپایل شود و یک فایل با نام HelloWorldApp.class تولید کند. در آن موقع می تواند اجرا یا راه اندازی شود. فایل منبع جاوا می تواند فقط حاوی یک کلاس Public باشد، اما می تواند حاوی چندین کلاس دیگر با دسترسی غیر از Public و هر تعداد کلاس های داخلی Public باشد. وقتی فایل منبع حاوی چندین کلاس است، یکی از کلاس ها را Public کنید و فایل منبع را با اسم آن کلاس Public هم نام کنید.
یک کلاس که به عنوان Public اعلام نشده باشد را می توان در هر فایل جاوایی ذخیره کرد. کامپایلر یک فایل Class برای هر یک از کلاس های تعریف شده در فایل منبع تولید خواهد کرد. نام فایل کلاس با نام کلاس یکی است و پسوند .class دارد. برای تولید فایل Class، با کلاس های ناشناس طوری رفتار می شود که انگار نام آنها ترکیبی از نام کلاس اصلی، یک علامت $ و یک عدد صحیح است.
کلمه کلیدی Public نشان می دهد که یک متد را می توان از کد به کلاس های دیگر فراخوانی کرد یا یک کلاس می تواند توسط کلاس های دیگر در خارج از سلسله مراتب کلاس مورد استفاده قرار گیرد. سلسله مراتب کلاس با نام محلی که فایل java ذخیره شده است، ارتباط دارد. به این یک اصلاحگر سطح دسترسی گفته می شود دیگر اصلاحگرهای سطح دسترسی شامل کلمات کلیدی Private و Protected هستند.
کلمه کلیدی Static در جلوی یک متد نشان دهنده یک متد استاتیک است که تنها با کلاس ارتباط دارد، نه با نمونه های خاصی از آن کلاس. تنها متدهای استاتیک را می توان بدون مرجع به یه شیء، فراخوانی کرد. متدهای استاتیک نمی توانند به هیچ عضوی از کلاس که استاتیک نیستند، دسترسی داشته باشند. متدهایی که به عنوان استاتیک مشخص نشده اند، متدهای نمونه هستند و برای کار کردن نیازمند یک نمونه خاص از کلاس هستند.
کلمه کلیدی Void نشان می دهد که متد اصلی هیچ مقداری را به فراخوانی کننده تحویل نمی دهد. اگر یک برنامه جاوا بخواهد با یک کد ارور خارج شود، باید صریحا System.exit() را فراخوانی کند.
نام متد “main” در زبان برنامه نویسی Java یک کلمه کلیدی نیست، بلکه تنها نام متدی است که java launcher آن را فراخوانی می کند تا کنترل را به برنامه وارد کند. کلاس های جاوایی که در محیط های مدیریت شده مانند Appletها یا Enterprise JavaBeans اجرا می شوند، از یک متد main() استفاده نمی کنند و به آن نیازی ندارند. یک برنامه جاوا می تواند دارای چندین کلاس باشد که متد main دارند، یعنی به VM باید صریحا گفته شود که از کدام کلاس اجرا شود.
متد main باید یک آرایه از اشیای رشته ای را بپذیرد. بطور قراردادی به عنوان args به آن رفرنس داده می شود، اما هر شناسه قانونی دیگری را هم می توان استفاده کرد. از زمان java 5، متد اصلی همچنین می تواند از آرگومان های متغیر به صورت public static void main(String… args) استفاده کند تا به متد اصلی اجازه دهد با یک تعداد اختیاری از آرگومان های رشته ای فراخوانی شود. تاثیر این اعلان متناوب از نظر معنایی مشابه است (پارامتر args هنوز هم یه آرایه از اشیای رشته ای است)، اما به یک قاعده نحوی متناوب اجازه ساخت و وارد کردن آرایه را می دهد.
Java Launcher با لود کردن یک کلاس معین (که در خط فرمان یا به عنوان یک خصیصه در فایل JAR مشخص شده است)، جاوا را اجرا می کند و متد public static void main(String[]) را آغاز می کند. برنامه های مستقل باید این متد را صریحا اعلام کنند. پارامتر String[] args یک آرایه از اشیای رشته ای است که حاوی تمام آرگومان های وارد شده به کلاس است. پارامترهای main معمولا بوسیله یم خط فرمان وارد می شوند.
پرینت کردن هم بخشی از کتابخانه استاندارد جاوا است: کلاس System یک فیلد استاتیک Public به نام out را تعریف می کند. شیء out یک نمونه از کلاس PrintStream است و متدهای بسیاری برای پرینت کردن داده با خروجی های استاندارد فراهم می کند، از جمله println(String) که همچنین یک خط جدید به رشته وارد شده اضافه می کند. رشته “Hello World!” به طور خودکار توسط کامپایلر به یک شیء رشته ای تبدیل می شود.
مثال فراگیر
// OddEven.java import javax.swing.JOptionPane; public class OddEven { private int userInput; // a whole number("int" means integer) /** * This is the constructor method. It gets called when an object of the OddEven type * is being created. */ public OddEven() { /* * In most Java programs constructors can initialize objects with default values, or create * other objects that this object might use to perform its functions. In some Java programs, the * constructor may simply be an empty function if nothing needs to be initialized prior to the * functioning of the object. In this program's case, an empty constructor would suffice. * A constructor must exist; however, if the user doesn't put one in then the compiler * will create an empty one. */ } /** * This is the main method. It gets called when this class is run through a Java interpreter. * @param args command line arguments (unused) */ public static void main(final String[] args) { /* * This line of code creates a new instance of this class called "number" (also known as an * Object) and initializes it by calling the constructor. The next line of code calls * the "showDialog()" method, which brings up a prompt to ask you for a number. */ OddEven number = new OddEven(); number.showDialog(); } public void showDialog() { /* * "try" makes sure nothing goes wrong. If something does, * the interpreter skips to "catch" to see what it should do. */ try { /* * The code below brings up a JOptionPane, which is a dialog box * The String returned by the "showInputDialog()" method is converted into * an integer, making the program treat it as a number instead of a word. * After that, this method calls a second method, calculate() that will * display either "Even" or "Odd." */ userInput = Integer.parseInt(JOptionPane.showInputDialog("Please enter a number.")); calculate(); } catch (final NumberFormatException e) { /* * Getting in the catch block means that there was a problem with the format of * the number. Probably some letters were typed in instead of a number. */ System.err.println("ERROR: Invalid input. Please type in a numerical value."); } } /** * When this gets called, it sends a message to the interpreter. * The interpreter usually shows it on the command prompt (For Windows users) * or the terminal (For *nix users).(Assuming it's open) */ private void calculate() { if ((userInput % 2) == 0) { JOptionPane.showMessageDialog(null, "Even"); } else { JOptionPane.showMessageDialog(null, "Odd"); } } }
– عبارت Import، کلاس JOptionPane را از بسته javaz.swing وارد می کند.
– کلاس OddEven یک فیلد Private انفرادی از نوع int با نام userInput را اعلام می کند. هر نمونه از کلاس OddEven دارای یک نسخه از فیلد userInput می باشد. اعلان Private یعنی هیچ کلاس دیگری نمی تواند به فیلد userInput دسترسی داشته باشد و در آن خواندن و نوشتن انجام دهد.
– OddEven () یک Constructor یا سازنده Public است. Constructorها نامی مشابه با کلاسی که در آن اعلام شده اند، دارند و برخلاف متدها، هیچ نوع بازگشتی ندارند. از یک Constructor برای نمونه سازی از یک شیء استفاده می شود که یک نمونه تازه ساخته شده از یک کلاس است.
– متد calculate() بدون کلمه کلیدی static اعلان می شود. یعنی این متد با استفاده از یک نمونه خاص از کلاس oddEven فراخوانی می شود. (رفرنسی که برای فراخوانی متد استفاده می شود به عنوان یک پارامتر اعلام نشده از نوع OddEven با نام this وارد می شود.) این متد، عبارت userInput % 2 == 0 را با استفاده از کلمه کلیدی if آزمایش می کند تا ببیند که باقی مانده از تقسیم فیلد userInput که متعلق به نمونه کلاس است بر عدد دو، برابر با صفر است یا نه. اگر این عبارت صحت داشته باشد، کلمه Even را پرینت می کند و اگر غلط باشد، کلمه Odd را پرینت می کند. (به متد calculate از طریق this.calculate هم می توان بطور مشابهی دسترسی داشت و به فیلد userInput هم می توان this.userInput دسترسی داشت که هر دو صریحا از پارامتر اعلان نشده this استفاده می کنند).
– OddEven number = new OddEven(); یک متغیر مرجعی شیء محلی را در متد main به نام number مشخص می کند. این متغیر می تواند به یک شیء از نوع OddEven رفرنس داشته باشد. این اعلان در ابتدا با ساخت یک نمونه از کلاس OddEven با استفاده از کلمه کلیدی New و سازنده OddEven()، number را مقداردهی می کند و سپس این نمونه را به متغیر اختصاص می دهد.
– عبارت number.showDialog();، متد calculate را فراخوانی می کند. از نمونه شیء OddEven که متغیر محلی number به آن رفرنس داده است استفاده می شود تا متد فراخوانی شود و به عنوان پارامتر اعلان نشده this در متد calculate وارد می شود.
– userInput = Integer.parseInt(JOptionPane.showInputDialog(“Please Enter A Number”)); عبارتی است که با استفاده از یک تابع مطلوبیت در کلاس wrapper اولیه integer، نوع رشته ای را به نوع داده اولیه int تبدیل می کند.
کلاس های خاص
Applet
Appletهای جاوا برنامه هایی هستند که در برنامه های دیگر تعبیه شده اند، عموما یک صفحه وب که در یک مرورگر وب نمایش داده می شود.
// Hello.java import javax.swing.JApplet; import java.awt.Graphics; public class Hello extends JApplet { public void paintComponent(final Graphics g) { g.drawString("Hello, world!", 65, 95); } }
عبارت import به کامپایلر جاوا دستور می دهد تا کلاس های javax.swing.JApplet java.awt.Graphics را در مجموعه شامل کند. عبارت import به این کلاس ها اجازه می دهد با استفاده از نام ساده کلاس (مانند JApplet) به جای نام کامل کلاس (مانند javax.swing.JApplet) در کد منبع به آنها اشاره شود.
کلاس Hello ، کلاس JApplet را تعمیم می دهد. کلاس JApplet، فریم ورک برنامه میزبان را فراهم می کند تا طول عمر Applet را نمایش داده و کنترل کند. کلاس JApplet یک JComponent است (مولفه گرافیکی جاوا) که به Applet قابلیت نمایش دادن یک محیط کاربری گرافیکی (GUI) و پاسخ به رویدادهای کاربر را می دهد.
کلاس Hello بر متد paintComponent(Graphics) که از سوپرکلاس container گرفته شده است تا کد برای نمایش دادن Applet را فراهم کند، اولویت دارد. در متد paintComponent() یک شیء Graphics وارد شده است که حاوی محتوای گرافیکی مورد استفاده برای نمایش دادن Applet است. متد paintComponent() محتوای گرافیکی کتد drawString(String, int, int) را فراخوانی می کند تا رشته “Hello, world!” را با آفست (65, 95) پیکسل از گوشه سمت چپ بالای صفحه نمایش Applet، نمایش دهد.
یک Applet با استفاده از عنصر اچ تی ام ال <applet> در سند HTML قرار داده می شود. تگ applet سه مجموعه خصیصه دارد: code=”Hello” نام کلاس JApplet را تعیین می کند و width=”200″ height=”200″ مقدار عرض و ارتفاع applet را مشخص می کند. Appletها را همچنین می توان با استفاده از عنصر Object یا embed در HTML تعبیه کرد، البته پشتیبانی از این عناصر توسط مرورگرهای وب دارای ثبات نیست. هرچند، تگ applet منسوخ شده است، بنابراین تگ object ترجیح داده می شود.
برنامه میزبان که معمولا یک مرورگر وب است، applet را نمونه سازی می کند و یک AppletContext برای applet می سازد. وقتی applet نمونه سازی شد، به سلسله مراتب نمایش AWT افزوده می شود. هر موقع که صفحه نمایش نیاز دارد تا applet خود را اجرا کند، متد paintComponent() توسط AWT فراخوانی می شود.
Servlet
تکنولوژی Java Servlet به توسعه دهندگان وب، یک مکانیزم ساده و یکنواخت برای تعمیم دادن کارایی سرور وب و برای دسترسی به سیستم های تجاری موجود، ارائه می کند. Servletها، مولفه های سمت سرور Java EE هستند که به درخواست های مشتریان، پاسخ می دهند. یک Servlet را تقریبا می توان یک applet در نظر گرفت که در سمت سرور به صورت ناشناس اجرا می شود.
// Hello.java import java.io.*; import javax.servlet.*; public class Hello extends GenericServlet { public void service(final ServletRequest request, final ServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); final PrintWriter pw = response.getWriter(); try { pw.println("Hello, world!"); } finally { pw.close(); } } }
عبارت import به کامپایلر جاوا دستور می دهد تا تمام کلاس ها و رابط های کاربری Public از بسته های java.io و javax.servlet را در مجموعه شامل کند. این بسته ها باعث می شوند که زبان برنامه نویسی Java برای برنامه های با مقیاس بزرگ مناسب باشد.
کلاس Hello ، کلاس GenericServlet را تعمیم می دهد. کلاس GenericServlet، رابط کاربری را برای سرور فراهم می کند تا درخواست های Servlet را فوروارد کرده و چرخه عمر Servlet را کنترل کند.
کلاس Hello بر متد service(ServletRequest, ServletResponse) که توسط رابط کاربری Servlet تعریف شده است تا کد را برای Service Request Handler فراهم کند، اولویت دارد. در متد service() یک شیء ServletRequest وارد شده است که حاوی درخواست از طرف مشتری است و از یک شیء ServletRequest برای ساخت پاسخ به مشتری استفاده می شود. متد service() اعلام می کند که اگر یک مشکل مانع از پاسخ دادن به یک درخواست شود، استثنائات ServletException و IOException را اجرا می کند.
متد setContentType(String) در شیء پاسخ فراخوانی می شود تا نوع محتوای MIME داده بدست آمده را روی “text/html” تنظیم کند. متد getWriter() در پاسخ، یک شیء PrintWriter تحویل می دهد که برای نوشتن داده ای که برای مشتری ارسال شده است، استفاده می شود. متد println(String) فراخوانی می شود تا رشته “Hello, world!” در پاسخ نوشته شود و سپس متد close() فراخوانی می شود تا print writer بسته شود که باعث می شود داده ای که نوشته شده است، به مشتری بازگردانده شود.
صفحات JavaServer
صفحات JavaServer (JSP)، مولفه های سمت سرور Java EE هستند که پاسخ هایی را معمولا به صورت صفحات HTML برای درخواست های مشتریان ایجاد می کنند. JSPها، کدهای جاوای را با استفاده از جداکننده های خاص <% و %> در یک صفحه HTML تعبیه می کنند. اولین باری که به یک JSP دسترسی پیدا کنیم، در یک Java Servlet که خودش یک برنامه جاوا است، کامپایل می شود. بعد از آن، Servlet ساخته شده، پاسخ را ایجاد می کند.
برنامه Swing
Swing یک کتابخانه رابط کاربری گرافیکی برای پلتفرم Java SE است. می توان یک ظاهر و حس متفاوتی از طریق سیستم pluggable look and feel در Swing ایجاد کرد. کپی های Windows، GTK+ و Motif توسط شرکت Sun تامین شده اند. شرکت Apple هم یک ظاهر و حس آب با تم Aqua برای Mac OS X ایجاد کرد. درحالیکه این ظاهرها و نماها ممکن است در گذشته اجرا نشده باشند، اما Swing در Java SE 6 این را مشکل را رفع می کند و از شیوه های طراحی ویجت GUI محلی پلتفرم ها استفاده می کند.
این برنامه نمونه Swing یک پنجره با عبارت “Hello, World” در داخلش ایجاد می کند:
// Hello.java (Java SE 5) import javax.swing.*; public class Hello extends JFrame { public Hello() { super("hello"); super.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); super.add(new JLabel("Hello, world!")); super.pack(); super.setVisible(true); } public static void main(final String[] args) { new Hello(); } }
اولین import حاوی تمام کلاس ها و رابط های کاربری Public از بسته javax.swing است.
کلاس Hello، کلاس JFrame را تعمیم می دهد. کلاس JFrame یک پنجره با یک نوار عنوان و یک کنترل بسته می سازد.
سازنده Hello()، فریم را مقداردهی می کند و اول سازنده سوپرکلاس را فراخوانی می کند و پارامتر hello را وارد می کند که به عنوان نام پنجره استفاده می شود. سپس متد setDefaultCloseOperation(int) که از JFrame به ارث برده است را فراخوانی می کند تا عملیات پیش فرض هنگام انتخاب شدن کنترل روی نوار عنوان WindowConstants.EXIT_ON_CLOSE تنظیم شود. این باعث می شود زمانی که فریم بسته شود، JFrame حذف شود (به جای اینکه تنها مخفی شود) که این کار به ماشین مجازی جاوا اجازه می دهد خارج شود و برنامه بسته شود. سپس یک JLabel برای رشته “Hello, world!” ساخته می شود و متد add(Component) که از سوپرکلاس container به ارث برده شده است فراخوانی می شود تا Label به فریم اضافه شود. متد pack() که از سوپرکلاس window به ارث برده شده است، فراخوانی می شود تا اندازه پنجره و آرایش محتوایش مشخص شود.
متد main() زمانی که برنامه آغاز می شود، توسط ماشین مجازی جاوا فراخوانی می شود. یک فریم Hello جدید را می سازد و با فراخوانی کردن متد setVisible(boolean) که از سوپرکلاس component با پارامتر بولی true به ارث گرفته شده است، آن را نمایش می دهد. وقتی که فریم نمایش داده شد، خارج شدن از متد main باعث بسته شدن برنامه نمی شود، زیرا AWT تا زمانی که پنجره های سطح بالای Swing بسته نشوند، فعال باقی می ماند.
Genericها
در سال 2004، Genericها به عنوان بخشی از J2SE 5.0 به زبان برنامه نویسی Java اضافه شدند. پیش از معرفی Genericها، هر یک از اعلان های متغیرها باید از نوع خاصی می بودند. مثلا برای کلاس های container این یک مشکل است، زیرا هیچ راه ساده ای برای ساخت یک container که تنها انواع خاصی از اشیا را می پذیرد، وجود ندارد. یا container روی تمام زیرنوع های یک کلاس یا رابط کاربری کار می کند که معمولا یک object است، یا یک کلاس container متفاوت باید برای هر یک از کلاس ها ساخته شود. Genericها بدون نیاز به ساختن کلاس های container زیادی که همه آنها تقریبا کد مشابهی دارند، اجازه چک کردن نوع در زمان کامپایل را می دهند. به علاوه نوشتن کدهای کارآمدتر، استثنائات Runtime خاصی به ارورهای زمان کامپایل تبدیل می شوند که به این خصیصه، type Safety گفته می شود.
انتقادات از زبان برنامه نویسی جاوا
انتقادهایی که در مورد زبان برنامه نویسی Java شده است شامل استفاده از Genericها، سرعت، کار با اعداد تخصیص نیافته، استفاده از ریاضیات با ممیز شناور و سابقه آسیب پذیری امنیتی در پیاده سازی اولیه Java VM در HotSpot است.
استفاده از زبان برنامه نویسی جاوا بر روی پلتفرم های نرم افزاری غیر رسمی
زبان برنامه نویسی Java نیازمند حضور یک پلتفرم نرم افزاری است تا برنامه های کامپایل شده بتوانند اجرا شوند. یک پلتفرم نرم افزاری مشابه جاوای غیر رسمی معروف، پلتفرم نرم افزاری Android است که اجازه استفاده از Java 6 و برخی از ویژگی های Java 7 را می دهد، از یک کتابخانه استاندارد متفاوت (پیاده سازی مجدد Apache Harmony)، زبان بایت کد متفاوت و ماشین مجازی متفاوت استفاده می کند و برای دستگاه هایی با حافظه پایین مانند گوشی های هوشمند و کامپیوترهای تبلت طراحی شده است.
زبان برنامه نویسی جاوا، یک ستون اصلی در سیستم عامل موبایل کد باز اندروید است. گرچه اندروید روی هسته Linux ساخته شده است و بیشتر در زبان C نوشته شده است، اما Android SDK از زبان برنامه نویسی جاوا به عنوان مبنای برنامه های اندروید استفاده می کند. هرچند، اندروید از ماشین مجازی جاوای استاندارد استفاده نمی کند، بلکه از Java Bytecode به عنوان یک گام میانی استفاده می کند که به Dalvik Bytecode تبدیل می شود. بسته به ورژن اندروید، این یا بوسیله ماشین مجازی Dalvik تفسیر می شود، یا توسط Android Runtime به صورت کد محلی کامپایل می شود.
اندروید همچنین کتابخانه استاندارد Java SE کامل را ارائه نمی کند، گرچه کتابخانه کلاس اندروید شامل یک پیاده سازی مستقل از زیرمجموعه بزرگی از آن است. این امر منجر به ایجاد یک دعوی قانونی بین شرکت های Oracle و Google شد. در 7 می سال 2012، یک قاضی در سان فرانسیسکو پی برد که اگر APIها می توانند کپی رایت داشته باشند، بنابراین گوگل با استفاده کردن از زبان برنامه نویسی Java در دستگاه های اندروید، حقوق کپی رایت شرکت Oracle را نقض کرده است. ویلیام هاسکل السوپ، قاضی بخش در 31 می سال 2012 حکم داد که APIها نمی توانند کپی رایت داشته باشند، اما این حکم در می سال 2014 توسط دادگاه تجدید نظر فدرال ایالات متحده لغو شد.
کتابخانه های کلاس
کتابخانه کلاس جاوا یک کتابخانه استاندارد است که برای پشتیبانی از توسعه برنامه در جاوا ساخته شده است. این کتابخانه توسط شرکت Sun Microsystems به همراه دیگران از طریق برنامه Java Community Process کنترل می شود. شرکت ها یا افرادی که در این فرایند شرکت می کنند می توانند روی طراحی و توسعه APIها تاثیر بگذارند. این فرایند موضوع بحث های بسیاری بوده است. کتابخانه کلاس، شامل ویژگی های نظیر زیر است:
– کتابخانه های مرکزی که شامل موارد زیر هستند:
– IO/NIO
– شبکه
– بازتاب
– هم زمانی
– Genericها
– اسکریپت نویسی / کامپایلر
– برنامه نویسی تابعی
– کتابخانه های Collection که ساختارهای داده ای مانند لیست ها، دیکشنری ها، درخت ها، مجموعه ها، صف ها و صف های دو طرفه یا Stack ها را بکار می برند.
– کتابخانه های پردازش XML (تجزیه، تبدیل، اعتبارسنجی)
– امنیت
– کتابخانه های بین المللی سازی و بومی سازی
– کتابخانه های یکپارچه سازی که به برنامه نویس اجازه می دهند با سیستم های External ارتباط برقرار کند. این کتابخانه ها شامل موارد زیر هستند:
– API اتصال پایگاه داده جاوا (JDBC) برای دسترسی به پایگاه داده
– رابط کاربری نامگذاری و دایرکتوری جاوا (JNDI) برای جسنجو و کشف
– RMI و CORBA برای توسعه برنامه توزیع شده
– JMX برای مدیریت و نظارت روی برنامه ها
– کتابخانه های رابط کاربری شامل موارد زیر هستند:
– Abstract Window Toolkit (AWT) (سنگین وزن یا محلی) که مولفه های GUI ، روشی برای چیدمان آن مولفه ها و راهی برای مدیریت رویدادها از آن مولفه ها فراهم می کند.
– کتابخانه های (سبک وزن) Swing که بر مبنای AWT ساخته شده اند، اما کاربردهای (غیر محلی) از ابزارهای AWT فراهم می کنند.
– APIها برای ضبط، پردازش و پخش صدا
– JavaFX
– یک اجرای مبتنی بر پلتفرم ماشین مجازی جاوا که راهی برای اجرا شدن کتابخانه های جاوا و برنامه های ثالث است.
– پلاگین ها که اجازه می دهند appletها در مرورگرها اجرا شوند.
– Java Web Start که به برنامه های جاوا اجازه می دهد بطور کارآمد در بین کاربران نهایی در سراسر اینترنت توزیع شوند.
– مجوز و مستندات
مستندات زبان برنامه نویسی جاوا
Javadoc یک سیستم سندسازی جامع است که توسط شرکت Sun Microsystems ساخته شده و توسط بسیاری از توسعه دهندگان زبان برنامه نویسی Java مورد استفاده قرار می گیرد. Javadoc به توسعه دهندگان یک سیستم سازمان دهی شده برای مستندسازی کدهایشان می دهد. کامنت های Javadoc یک ستاره اضافی در ابتدا دارند. برای مثال، جداکننده آن /** و */ هستند، درحالیکه کامنت های چند خطی عادی با جداکننده های /* و */ مشخص می شوند.
نسخه های زبان برنامه نویسی جاوا
شرکت Sun چهار نسخه از جاوا را برای محیط های برنامه مختلف ساخته است و بسیاری از APIهایش را تقسیم کرده است تا به یکی از پلتفرم ها تعلق داشته باشند. این پلتفرم ها شامل موارد زیر هستند:
– Java Card برای کارت های هوشمند
– پلتفرم جاوا، نسخه Micro (Java ME) – برای محیط هایی با منابع محدود.
– پلتفرم جاوا، نسخه استاندارد (Java SE) – برای محیط های کاری.
– پلتفرم جاوا، نسخه Enterprise (Java EE) – برای محیط های سازمانی یا اینترنتی توزیع شده بزرگ.
کلاس های موجود در API جاوا در گروه های مختلف به نام بسته ها یا Packageها دسته بندی شده اند. هر بسته حاوی مجموعه ای از Interfaceها، کلاس ها و استثنائات است. برای دیدن توضیحات بسته های موجود، به پلتفرم ها مراجعه کنید. شرکت Sun همچنین یک نسخه به نام PersonalJava ارائه کرده است که بعدها توسط جفت های پیکربندی پروفایل Java ME مبتنی بر استانداردها، جایگزین شده است.
منابع: ویکی پدیا انگلیسی ، وبسایت Oracle ، آریا گستر و …
توصیه می کنیم دوره های جامع فارسی مرتبط با این موضوع آریاگستر را مشاهده کنید:
– صفر تا صد آموزش اندروید با اندروید استودیو
– صفر تا صد آموزش اندروید با اکلیپس
– صفر تا صد آموزش بازی سازی موبایل با Android SDK
– محصولات آموزشی مرتبط با برنامه نویسی
توجه : مطالب و مقالات وبسایت آریاگستر تماما توسط تیم تالیف و ترجمه سایت و با زحمت فراوان فراهم شده است . لذا تنها با ذکر منبع آریا گستر و لینک به همین صفحه انتشار این مطالب بلامانع است !
دوره های آموزشی مرتبط
350,000 تومان
350,000 تومان
مطالب مرتبط
قوانین ارسال دیدگاه در سایت
- چنانچه دیدگاهی توهین آمیز یا بی ارتباط با موضوع آموزش باشد تایید نخواهد شد.
- چنانچه دیدگاه شما جنبه ی تبلیغاتی داشته باشد تایید نخواهد شد.
ممنون از سایت خوبتون. یک سوال داشتم، به مناسب دهه فجر برای محصولاتتون تخفیف نگذاشتید؟
خیلی مطلب کاربردی هست. با تشکر از شما