الهدف من هذه الدورة هو مساعدتك في استخدام جافا بشكل أكثر فعالية. هناك بعض الموضوعات المتقدمة التي تمت مناقشتها ، بما في ذلك إنشاء الكائنات ، والتزامن ، والتسلسل ، والتفكير ، والميزات المتقدمة الأخرى. سوف توجه هذه الدورة رحلتك لكفاءة جافا.
1. مقدمة
في ترتيب لغة برمجة Tiobe ، تعد لغة Java التي طورتها Sun في عام 1995 واحدة من أكثر لغات البرمجة استخدامًا في العالم. كلغة برمجة عامة ، تعتبر لغة Java جذابة للغاية لمهندسي تطوير البرمجيات نظرًا لبيئة أدواتها القوية وبيئة وقت التشغيل ، وبناء بناء جملة ، ودعم منصة غنية (مكتوب في وقت واحد ، وركض في كل مكان) ودعم مجتمعي نشط للغاية.
في هذه السلسلة من المقالات ، تتم تغطية المحتوى المتقدم المتعلق بـ Java ، لذلك من المفترض أن يكون للقارئ بالفعل معرفة اللغة الأساسية. هذا ليس دليل مرجعي كامل ، ولكنه دليل شامل لأخذ مهاراتك إلى المستوى التالي.
تحتوي هذه الدورة على عدد كبير من مقتطفات التعليمات البرمجية. من أجل إجراء مقارنات ، ستوفر بعض الأطراف الأخرى أمثلة على Java 7 و Java 8 في نفس الوقت.
2. مثال البناء
كلغة موجهة إلى الكائن ، ربما يكون إنشاء الكائنات أحد أهم المفاهيم في لغة Java. يلعب المنشئ دورًا مهمًا في تهيئة مثيلات الكائن ، وتوفر Java مجموعة متنوعة من الطرق لتحديد المنشئين.
2.1 طريقة البناء الضمنية (المولدة)
لا يسمح Java بأي مُنشئين عند تحديد الفصول الدراسية ، وهذا لا يعني أنه لا يوجد مُنشئ. دعونا نلقي نظرة على تعريف الفصل التالي:
حزمة com.javacodegekes.advanced.construction ؛ فئة عامة noconstructor {}لا تحدد هذه الفئة مُنشئًا ، لكن برنامج التحويل البرمجي Java سيولد ضمنيًا له ، مما يسمح لنا باستخدام الكلمة الرئيسية الجديدة لإنشاء مثيلات كائن جديدة.
النهائي noconstructor noconstructorinstance = جديد noconstructor () ؛
2.2 طريقة البناء بدون معلمة
مُنشئ المعلمة هو أسهل طريقة لاستبدال تجميع Java وإنشاء مُنشئين بإعلانات واضحة.
package com.javacodegeeks.advanced.construction ؛ الطبقة العامة noargconstructor {public noargconstructor () {// body body هنا}}عند إنشاء مثيل كائن جديد باستخدام الكلمة الرئيسية الجديدة ، سيتم استدعاء المنشئ أعلاه.
2.3 طريقة بناء تشبه المعلمة
طريقة بناء المعلمات هي الأكثر إثارة للاهتمام والاستخدام على نطاق واسع ، ويتم تخصيص مثيلات جديدة من خلال تحديد المعلمات. يحدد المثال التالي مُنشئًا مع معلمتين.
package com.javacodegeeks.advanced.construction ؛ constructorgenments {Public ConstructorWithArguments (السلسلة النهائية Arg1 ، السلسلة النهائية Arg2) {// body Body Here}}في هذا السيناريو ، عند استخدام الكلمة الرئيسية الجديدة لإنشاء مثيل ، يجب توفير معلمتان محددتان على طريقة البناء في نفس الوقت.
البناء النهائي constructorWithArguments = constructorWithArguments ("arg1" ، "arg2") ؛ومن المثير للاهتمام ، يمكن استدعاء المُنشئين لبعضهم البعض من خلال هذه الكلمة الرئيسية. في الممارسة العملية ، يوصى بسلسلة مُنشئين متعددة باستخدام هذا لتقليل ازدواجية الكود ولإدخال تهيئة واحد استنادًا إلى الكائن. على سبيل المثال ، يحدد الكود التالي مُنشئًا بمعلمة واحدة فقط.
البناء العام itharguments (السلسلة النهائية Arg1) {this (Arg1 ، Null) ؛}2.4 تهيئة كتلة الكود
بالإضافة إلى بناء الأساليب ، توفر Java أيضًا المنطق لتهيئة تهيئة كتل التعليمات البرمجية. على الرغم من أن هذا الاستخدام نادر ، إلا أنه ليس ضارًا لمعرفة المزيد عن ذلك.
حزمة com.javacodegeeks.advanced.construction ؛ فئة عامة التهيئة {{// رمز التهيئة هنا}}من ناحية أخرى ، يمكن أيضًا اعتبار كتل الكود تهيئة طرق بناء ضمنية بدون معلمات. في فئة محددة ، يمكن تعريف كتل رمز التهيئة المتعددة ، ويتم استدعاؤها بالترتيب الذي تكون فيه في الرمز عند تنفيذها ، كما هو موضح في الكود التالي:
package com.javacodegeeks.advanced.construction ؛ initializationblocks {{// رمز التهيئة هنا} {// رمز التهيئة هنا}}لا يجب استبدال كتل التعليمات البرمجية حقًا ، ولكن يمكن أن تظهر في وقت واحد. ولكن تذكر أنه سيتم تنفيذ رمز التهيئة قبل أن تكون مكالمة طريقة المنشئ قريبًا.
package com.javacodegeeks.advanced.construction ؛ public initializationBlockAndConstructor {{// رمز التهيئة هنا} publicizationblockandconstructor () {}}2.5 ضمان بناء القيم الافتراضية
يوفر Java ضمان تهيئة محدد ، ويمكن للمبرمجين استخدام نتيجة التهيئة مباشرة. سيتم تلقائيًا تلقائيًا تلقائيًا تلقائيًا تلقائيًا تلقائيًا تلقائيًا تلقائيًا إلى القيم الافتراضية المقابلة.
اكتب القيمة الافتراضية
BooleAnfalse
BYTE0
قصيرة 10
int0
Long0l
char/u0000
float0.0f
double0.0d
مرجع الكائن الفارغ
الجدول 1
نستخدم المثال التالي للتحقق من القيم الافتراضية في الجدول أعلاه:
package com.javacodegeeks.advanced.construction ؛ تهيئة الطبقة العامة مع DiThDefaults {private booleanmeanmmember ؛ بايت بايت بايت. أفراد قصير قصير ؛ خاص intmember ؛ عضو طويل طويل طويل ؛ شار تشارمبرز الخاص ؛ عائم خاص عائم. ديسمبر المزدوج الخاص كائن خاص إشارة ؛ التهيئة العامة withdefaults () {system.out.println ("booleAnmmember =" + booleanmember) ؛ system.out.println ("bytemmed =" + bytemmed) ؛ System.out.println ("ShortMember =" + Shortmember) ؛ System.out.println ("IntMember =" + IntMember) ؛ System.out.println ("LongMember =" + LongMember) ؛ System.out.println ("charmember =" + character.codepointat (new char [] {Charmember} ، 0)) ؛ system.out.println ("floatmember =" + floatmember) ؛ System.out.println ("Doublembem =" + Doublemember) ؛ system.out.println ("referencemmed =" + referencemember) ؛ }}بعد إنشاء الكائن باستخدام الكلمة الرئيسية الجديدة:
التهيئة النهائية withDefaults تهيئة withDefaults = جديد التهيئة withDefaults () ،
يمكنك رؤية نتيجة الإخراج من وحدة التحكم على النحو التالي:
BooleAnmember = falseByTemmember = 0shortMember = 0intMember = 0longmember = 0Charmember = 0floatmember = 0.0doublemember = 0.0referencemm.
2.6 الرؤية
يتبع المنشئ قواعد رؤية Java ، ويمكنه تحديد ما إذا كان يمكن استدعاء المُنشئ في فئات أخرى من خلال معدلات التحكم في الوصول.
وضوح حزمة المعدل رؤية الفئة الفرعية رؤية عامة الرؤية العامة
مرئية مرئية مرئية مرئية مرئية مرئية مرئية
محمية مرئية مرئية ، غير مرئية غير مرئية غير مرئية
<لا يوجد تعديل> مرئي ، غير مرئي ، غير مرئي
خاص غير مرئي غير مرئي غير مرئي الجدول 2
2.7 إعادة تدوير القمامة
Java (JVM لتكون دقيقة) لديها آلية جمع القمامة التلقائي. ببساطة ، عند إنشاء كائن جديد ، سيتم تخصيصه تلقائيًا ؛ ثم عندما لا يتم الرجوع إلى الكائن ، سيتم تدميرها تلقائيًا وسيتم إعادة تدوير الذاكرة المقابلة.
تتبنى مجموعة Java Garbage آلية لإعادة تدوير الأجيال وتستند إلى افتراض أن "معظم الأشياء لها حياة قصيرة" (أي أنها لن تتلى بعد وقت قصير من إنشاء الكائن ، بحيث يمكن تدميرها بأمان). يعتقد معظم المبرمجين عادة أن إنشاء الكائنات في جافا غير فعال للغاية ، لذلك ينبغي عليهم تجنب إنشاء كائنات جديدة قدر الإمكان. في الواقع ، هذا الفهم خاطئ. النفقات العامة لإنشاء كائنات في Java منخفض وسريع للغاية. إن النفقات العامة الضخمة للجيل الحقيقي هي كائنات البقاء على المدى الطويل غير الضرورية ، لذلك سيتم في النهاية ترحيلها إلى الشيخوخة وتتسبب في حدوث إيقاف العالم.
2.8 الكائنات النهائية
لقد تحدثنا عن الموضوعات المتعلقة بطرق البناء وتهيئة الكائن ، لكننا لم نذكر جانبهم السلبي: تدمير الكائن. ويرجع ذلك أساسًا إلى أن Java تستخدم آليات جمع القمامة لإدارة دورة حياة الكائنات ، وتدمير الكائنات غير الضرورية وتحرير الذاكرة المطلوبة تصبح مسؤولية جمع القمامة.
ومع ذلك ، لا تزال Java توفر ميزة أخرى مشابهة لـ Destructor Finalizer ، والتي تتحمل مسؤولية تنظيف موارد متعددة. يُنظر إلى Finalizer عمومًا على أنه أمر خطير (لأنه يمكن أن يجلب مجموعة متنوعة من الآثار الجانبية وقضايا الأداء). عادة ، لا يلزم Finalizer ، لذا حاول تجنب ذلك (باستثناء السيناريوهات النادرة التي تحتوي على عدد كبير من الكائنات الأصلية). يمكن استخدام بناء جملة المحاولة مع الموارد والواجهة التلقائية المقبولة في Java 7 كبدائل للنهائيات ، ويمكن كتابة الرمز الموجز التالي:
جرب (Final inputStream في = files.newInputStream (path)) {// code هنا}3. التهيئة الثابتة
أعلاه تعلمنا عن بناء وتهيئة مثيلات الفصل. بالإضافة إلى ذلك ، تدعم Java أيضًا بناء التهيئة على مستوى الفصل ، وتسمى التهيئة الثابتة. تشبه التهيئة الثابتة كتلة رمز التهيئة الموضحة أعلاه ، باستثناء أن هناك تعديلات إضافية في الكلمات الرئيسية الثابتة. تجدر الإشارة إلى أن التهيئة الثابتة لن يتم تنفيذها إلا مرة واحدة عند تحميل الفصل. الأمثلة على النحو التالي:
على غرار كتل تهيئة التعليمات البرمجية ، يمكن تعريف كتل التهيئة الثابتة المتعددة في فئة ما ، ويحدد موضعها في الفصل الترتيب الذي يتم تنفيذه عند التهيئة. أمثلة على النحو التالي ؛
package com.javacodegeeks.advanced.construction ؛ فئة عامة staticinitializationBlocks {static {// رمز التهيئة الثابت هنا} ثابت {// رمز التهيئة الثابتة هنا}}نظرًا لأنه يمكن تشغيل كتل التهيئة الثابتة بواسطة مؤشرات ترابط متعددة تنفذ بالتوازي (عندما يتم تحميل الفئة في البداية) ، يضمن وقت تشغيل JVM تنفيذ الرمز المهيئة مرة واحدة فقط في طريقة آمنة مؤشرات الترابط.
4. وضع المنشئ
تم تقديم مجموعة متنوعة من أنماط مُنشئ (منشئ) سهلة الفهم إلى مجتمع Java على مر السنين. أدناه سوف نتعلم بعضًا من أكثرها شعبية: وضع Singleton ، ووضع الفئة المساعدة ، ووضع المصنع ، وحقن التبعية (المعروف أيضًا باسم انعكاس التحكم).
4.1 وضع Singleton
Singleton هو تاريخ طويل ولكنه نموذج مثير للجدل في مجتمع تطوير البرمجيات. يتمثل المفهوم الأساسي لنمط Singleton في التأكد من إنشاء فئة معينة في أي وقت كائن واحد فقط. على الرغم من أن الأمر يبدو بسيطًا ، إلا أن هناك الكثير من النقاش حول كيفية إنشاء كائنات بطريقة صحيحة وآمنة. يعرض الرمز التالي نسخة بسيطة من تطبيق نمط Singleton:
package com.javacodegeeks.advanced.construction.patterns ؛ public class naivesingleton {private static naivesingleton مثيل ؛ private naivesingleton () {} static static public naivesingleton getInstance () {if (easty == null) {مثيل = new naivesingleton () ؛ } مثيل الإرجاع ؛ }}هناك مشكلة واحدة على الأقل في الكود أعلاه: يمكن إنشاء كائنات متعددة في سيناريو التزامن متعدد الخيوط. تتمثل إحدى الطرق المعقولة للتنفيذ (ولكن ليس تأخير التحميل) في استخدام خاصية static`final "للفئة. على النحو التالي:
الخاصية النهائية لل class.package com.javacodegeeks.advanced.construction.patterns ؛ الطبقة العامة eagersingleton {private static final eagersingleton مثيل = new Eagersingleton () ؛ Private Eagersingleton () {} eagersingleton getInstance () {return مثيل ؛ }}إذا كنت لا ترغب في إهدار الموارد القيمة وتريد إنشاء كائنات Singleton فقط عندما تكون هناك حاجة إليها حقًا ، فأنت بحاجة إلى استخدام طريقة التزامن واضحة. قد تقلل هذه الطريقة من التزامن في البيئات متعددة الخيوط (سيتم وصف مزيد من التفاصيل حول تزامن Java في أفضل ممارسات Java Advanced 9 Currency).
package com.javacodegeeks.advanced.construction.patterns ؛ الطبقة العامة Lazysingleton {مثيل Lazysingleton الخاص ؛ private lazysingleton () {} lazysingleton getInstance () {if (مثيل == null) {مثيل = new lazysingleton () ؛ } مثيل الإرجاع ؛ }}في الوقت الحاضر ، لم تعد أنماط Singleton خيارًا جيدًا في العديد من السيناريوهات لأنها تجعل الكود أقل سهولة في الاختبار. بالإضافة إلى ذلك ، فإن توليد وضع حقن التبعية يجعل وضع Singleton غير ضروري أيضًا.
4.2 الأدوات/الفصول المساعدة
تحظى نمط فئة الأدوات/فئة المساعدة بشعبية كبيرة بين مطوري Java. يتمثل مفهومها الأساسي في استخدام الفئات غير المقصودة (من خلال إعلان المنشئين الخاصين) ، وسيتم تقديم اختياري نهائي (مزيد من التفاصيل حول إعلان الفئات النهائية في تصميمات Java Advanced 3-Class و Onterface) والأساليب الثابتة. الأمثلة على النحو التالي:
package com.javacodegeeks.advanced.construction.patterns ؛ الفئة النهائية العامة HelperClass {private HelperClass () {} public static void helpermethod1 () {// method body here} public static void helpermethod2 () {// method body}}}}يعتقد العديد من المطورين ذوي الخبرة أن هذا النمط سيجعل فصول الأدوات حاوية لمختلف الأساليب غير ذات الصلة. نظرًا لأن بعض الطرق لا تحتوي على موضع مناسب ولكن يجب استخدامها من قبل فئات أخرى ، فسيتم وضعها عن طريق الخطأ في فئة الأدوات. يجب أيضًا تجنب هذا التصميم في معظم السيناريوهات: ستكون هناك دائمًا طرق أفضل لإعادة استخدام الرمز ، والحفاظ على الكود واضحًا وموجزًا.
4.3 نموذج المصنع
أثبت نموذج المصنع أنه أداة قوية للغاية للمطورين ، وهناك العديد من الطرق لتنفيذها في Java: أساليب المصنع والمصانع التجريدية. أسهل مثال هو استخدام الطريقة الثابتة لإرجاع مثيل لفئة معينة (طريقة المصنع) ، على النحو التالي:
package com.javacodegeeks.advanced.construction.patterns ؛ كتاب الفئة العامة {كتاب خاص (عنوان السلسلة النهائية) {} كتاب ثابت عام جديد (عنوان السلسلة النهائية) {return new book (title) ؛ }}على الرغم من أن استخدام هذه الطريقة يمكن أن يحسن من قابلية قراءة الكود ، إلا أنه من المثير للجدل في كثير من الأحيان أنه من الصعب إعطاء سيناريوهات مصنع Newbook أكثر ثراءً. هناك طريقة أخرى لتنفيذ نمط المصنع وهي استخدام واجهات أو فصول تجريدية (مصانع مجردة). على النحو التالي ، نحدد واجهة المصنع:
الواجهة العامة bookFactory {book newbook () ؛}اعتمادًا على معرض الصور ، يمكن أن يكون لدينا العديد من تطبيقات NewBook المختلفة:
مكتبة الفئة العامة تنفذ bookFactory {Override Public Book NewBook () {return New Paperbook () ؛ }} الفئة العامة kindlelibrary تنفذ bookFactory {Override Public Book NewBook () {return new KindleBook () ؛ }}الآن ، تطبيقات مختلفة من BookFactory تمنع الاختلافات في كتب محددة ، ولكن توفر طريقة جديدة جديدة.
4.4 حقن التبعية
يعتبر مصممي الفصل حقن التبعية (المعروف أيضًا باسم انقلاب التحكم) بممارسة التصميم الجيدة: إذا كانت بعض الحالات الفئة تعتمد على مثيلات الفصول الأخرى ، فيجب توفير (حقن) الحالات المعتمدة (حقن) من خلال طرق المنشئ (أو طرق المستقرة ، والسياسات ، وما إلى ذلك) ، بدلاً من أن يتم إنشاؤها بواسطة المثال نفسه. لنلقي نظرة على الكود التالي:
package com.javacodegeeks.advanced.construction.patterns ؛ استيراد java.text.dateformat ؛ استيراد java.util.date ؛ تعتمد على الفئة العامة {private final dateformat format = dateFormat.getDateinStance () ؛ تنسيق السلسلة العامة (تاريخ التاريخ النهائي) {return format.format (date) ؛ }}تتطلب الفئة التابعة مثيلًا لفئة DateFormat ويتم الحصول عليها بواسطة DateFormat.getDateInstance () عند إنشاء مثيل للكائن. يجب أن تفعل طريقة أفضل للشيء نفسه من خلال بناء معلمات الطريقة:
package com.javacodegeeks.advanced.construction.patterns ؛ import java.text.dateformat ؛ import java.util.date ؛ public class Assial {private final dateformat format ؛ المعتمدة العامة (تنسيق DateFormat النهائي) {this.format = format ؛ } تنسيق السلسلة العامة (تاريخ التاريخ النهائي) {return format.format (date) ؛ }}في المثال أعلاه ، يتم توفير جميع تبعيات مثيل الفصل خارجيًا ، مما يجعل من السهل تعديل DateFormat وسهل كتابة رمز الاختبار.