البرمجة العامة في جافا

تُعدّ الأنواع العامة إحدى ميزات البرمجة العامة التي أُضيفت إلى لغة جافا البرمجية عام ٢٠٠٤ ضمن الإصدار J2SE ٥.٠. صُممت هذه الأنواع لتوسيع نظام أنواع جافا ، مما يسمح "للنوع أو الدالة بالعمل على كائنات من أنواع مختلفة مع ضمان سلامة النوع أثناء الترجمة". [ ١ ] يتطلب جانب سلامة النوع أثناء الترجمة عدم تنفيذ الدوال متعددة الأشكال ذات المعاملات في آلة جافا الافتراضية ، إذ يستحيل ضمان سلامة النوع في هذه الحالة. [ ٢ ] [ ٣ ]

يدعم إطار عمل مجموعات جافا الأنواع العامة لتحديد نوع الكائنات المخزنة في مثيل المجموعة.

في عام 1998، ابتكر كل من جلعاد براخا ، ومارتن أوديرسكي ، وديفيد ستوتامير، وفيليب وادلر ، لغة جافا العامة، وهي امتداد للغة جافا لدعم الأنواع العامة. [ 4 ] تم دمج جافا العامة في جافا مع إضافة الأحرف البديلة .

التسلسل الهرمي والتصنيف

وفقًا لمواصفات لغة جافا : [ 5 ]

  • المتغير النوعي هو مُعرِّف غير مُؤهَّل. تُعرَّف المتغيرات النوعية من خلال تعريفات الفئات العامة، وتعريفات الواجهات العامة، وتعريفات الدوال العامة، وتعريفات المُنشئات العامة. غالبًا ما تكون هذه المُعرِّفات حرفًا كبيرًا واحدًا، ولكن تلك التي يزيد طولها عن حرف واحد تُكتب عادةً بأحرف كبيرة (على عكس لغات أخرى مثل C++ و C# و Rust حيث تُكتب بأحرف PascalCase )، على سبيل المثال . [ 6 ]java.util.PrimitiveIterator<T, T_CONS>
  • تُعتبر الفئة عامة إذا عرّفت متغير نوع واحد أو أكثر. [ 7 ] كما تُعرّف متغير نوع واحد أو أكثر يعمل كمعاملات. [ 8 ] يُعرّف تعريف الفئة العامة مجموعة من الأنواع المُعاملة، نوع واحد لكل استدعاء مُحتمل لقسم مُعاملات النوع. تشترك جميع هذه الأنواع المُعاملة في نفس الفئة أثناء التشغيل.
  • تُعتبر الواجهة عامة إذا كانت تُعلن عن متغير نوع واحد أو أكثر. [ 8 ] وهي تُعرّف متغير نوع واحد أو أكثر يعمل كمعاملات. [ 8 ] يُعرّف تعريف الواجهة العامة مجموعة من الأنواع، نوع واحد لكل استدعاء مُحتمل لقسم مُعاملات النوع. تشترك جميع الأنواع المُعاملة في نفس الواجهة أثناء التشغيل.
  • تُعتبر الدالة عامة إذا عرّفت متغيرًا واحدًا أو أكثر من متغيرات النوع. [ 9 ] تُعرف متغيرات النوع هذه باسم معاملات النوع الرسمية للدالة. ويتطابق شكل قائمة معاملات النوع الرسمية مع شكل قائمة معاملات النوع الخاصة بالفئة أو الواجهة.
  • يمكن تعريف الدالة البانية على أنها عامة، بغض النظر عما إذا كانت الفئة التي تُعرّف فيها عامة أم لا. تكون الدالة البانية عامة إذا عرّفت متغيرًا واحدًا أو أكثر من متغيرات النوع. تُعرف هذه المتغيرات بمعاملات النوع الرسمية للدالة البانية. يتطابق شكل قائمة معاملات النوع الرسمية مع شكل قائمة معاملات النوع في فئة أو واجهة عامة.

تحفيز

يوضح جزء كود جافا التالي مشكلةً تظهر عند عدم استخدام الأنواع العامة. أولًا، يُعلن عن متغير ArrayListمن النوع `string` Object. ثم يُضيف قيمةً java.lang.Stringإلى المتغير `string` java.util.ArrayList. أخيرًا، يحاول استرجاع القيمة المضافة java.lang.Stringوتحويلها إلى نوع java.lang.Integer`string` - وهذا خطأ منطقي، إذ يستحيل تحويل أي سلسلة نصية إلى عدد صحيح .

استيراد java.util.ArrayList ؛ استيراد java.util.List ؛List v = new ArrayList (); v.add ( " test" ); // سلسلة نصية لا يمكن تحويلها إلى عدد صحيح Integer i = ( Integer ) v.get ( 0 ) ; // خطأ أثناء التشغيل

وهذا يشبه لغة C ، التي تفتقر إلى الأنواع العامة، وعادة ما تخزن هياكل البيانات الشبيهة بالمجموعات البيانات على شكل void*( مؤشر فارغ )، والتي يجب تحويل الكائنات منها بشكل صريح.

على الرغم من أن الكود يُجمَّع بنجاح دون أخطاء، إلا أنه يُصدر استثناءً أثناء التشغيل java.lang.ClassCastExceptionعند تنفيذ السطر الثالث منه. يمكن اكتشاف هذا النوع من الأخطاء المنطقية أثناء التجميع باستخدام الأنواع العامة [ 8 ] ، وهو الدافع الرئيسي لاستخدامها [7]. يُعرِّف هذا النوع متغيرًا واحدًا أو أكثر من متغيرات النوع التي تعمل كمعاملات.

يمكن إعادة كتابة جزء الكود أعلاه باستخدام الأنواع العامة كما يلي:

استيراد java.util.ArrayList ؛ استيراد java.util.List ؛List <String> v = new ArrayList <String> ( ); v.add ( " test" ); Integer i = ( Integer ) v.get ( 0 ) ; // ( خطأ في النوع) خطأ في وقت الترجمة

يُحدد مُعامل النوع الموجود بين قوسَيjava.lang.String الزاوية أن الكائن يتكون من (أحد فروع المكونات العامة للكائن ). مع الأنواع العامة، لم يعد من الضروري تحويل السطر الثالث إلى أي نوع مُحدد، لأن نتيجة تُحدد بواسطة الكود الذي يُولّده المُصرّف .java.util.ArrayListjava.lang.Stringjava.util.ArrayListjava.lang.Objectv.get(0)java.lang.String

سيتم اكتشاف الخلل المنطقي في السطر الثالث من هذا الجزء كخطأ أثناء الترجمة (مع J2SE 5.0 أو أحدث) لأن المترجم سيكتشف أن v.get(0)القيمة تُرجع قيمة java.lang.Stringبدلاً من القيمة java.lang.Integer. [ 8 ] لمزيد من التفاصيل، انظر المرجع. [ 10 ]

إليكم مقتطفًا صغيرًا من تعريف الواجهات java.util.Listوفي java.util.Iteratorالحزمة java.util:

واجهة List <E> { void add ( E x ) ; Iterator <E> iterator ( ) ; }واجهة Iterator <E> { E next (); boolean hasNext ( ) ; }

تعريفات الفئات العامة

فيما يلي مثال على فئة جافا عامة، والتي يمكن استخدامها لتمثيل الإدخالات الفردية (تعيينات المفتاح إلى القيمة) في خريطة :

public class Entry < K , V > { private K key ; private V value ;public Entry ( K key , V value ) { this . key = key ; this . value = value ; }public K getKey () { return key ; }public V getValue () { return value ; }public String toString () { return String . format ( "(%s, %s)" , key , value ); } }

يمكن استخدام هذه الفئة العامة بالطرق التالية، على سبيل المثال:

Entry < String , String > grade = new Entry < String , String > ( "Mike" , "A" ) ; Entry < String , Integer > mark = new Entry < String , Integer > ( " Mike" , 100 ) ; System.out.printf ( "grade: %s%n" , grade ) ; System.out.printf ( " mark : %s%n" , mark ) ;Entry < Integer , Boolean > prime = new Entry <> ( 13 , true ) ; if ( prime.getValue ()) { System.out.println ( " % s هو عدد أولي .%n" , prime.getKey ( ) ) ; } else { System.out.println ( " % s ليس عددًا أوليًا.%n" , prime.getKey ( ) ) ; }

يُخرج ما يلي:

الدرجة: (مايك، أ) مارك: (مايك، 100) 13 عدد أولي. 

تعريفات الطرق العامة

فيما يلي مثال على طريقة عامة باستخدام الفئة العامة المذكورة أعلاه، لنوع عام T:

public static <T> Entry < T , T > twice ( T value ) { return new Entry < T , T > ( value , value ) ; }

ملاحظة: إذا قمنا بإزالة الأول <T>في الطريقة المذكورة أعلاه، فسنحصل على خطأ في الترجمة (لا يمكن العثور على الرمز " T")، لأنه يمثل تعريف الرمز.

في كثير من الحالات، لا يحتاج مستخدم الطريقة إلى تحديد معلمات النوع، حيث يمكن استنتاجها:

Entry < String , String > pair = Entry.twice ( " Hello " );

يمكن إضافة المعلمات بشكل صريح إذا لزم الأمر:

Entry < String , String > pair = Entry . <String> twice ( " Hello " );

لا يُسمح باستخدام الأنواع الأولية ، ويجب استخدام الإصدارات المُغلّفة بدلاً منها؛ ولا يُسمح بتخزين سوى الأنواع المرجعية في مُعامل النوع العام. على سبيل المثال، يفشل التجميع، ويجب بدلاً من ذلك استخدام فئات التغليف للأنواع الأولية (مثل .Entry<int,int>pair;Entry<Integer,Integer>pair;

كما توجد إمكانية لإنشاء طرق عامة بناءً على معلمات معينة.

public < T > T [] toArray ( T ... elements ) { return elements ; }

في مثل هذه الحالات، لا يمكن استخدام الأنواع الأولية أيضًا، على سبيل المثال:

Integer [] array = toArray ( 1 , 2 , 3 , 4 , 5 , 6 );

بينما لا يمكن تخزين القيم الأولية، يمكن تخزين مصفوفات القيم الأولية (لأنها كائنات وليست قيمًا أولية بحد ذاتها):

استيراد java.util.ArrayList ؛ استيراد java.util.List ؛// List<int[]> و List<Integer[]> مقبولتان بنفس القدر. List < int []> listOfArrays = new ArrayList <> (); List < Integer []> myOtherList = listOfArrays ;

مشغل الماس

باستخدام استنتاج النوع ، تسمح Java SE 7 والإصدارات الأحدث للمبرمج باستبدال زوج من الأقواس الزاوية الفارغة ( <>يُسمى " معامل المعين ") بزوج من الأقواس الزاوية التي تحتوي على مُعامل نوع واحد أو أكثر، والتي يُشير إليها سياق قريب بما فيه الكفاية . [ 11 ] على الرغم من <>أن يُطلق عليه غالبًا اسم "معامل المعين"، إلا أنه ليس مُعاملًا، بل مجرد قائمة مُعاملات نوع فارغة.

Entryوبالتالي، يمكن إعادة كتابة مثال الكود أعلاه على النحو التالي:

Entry < String , String > grade = new Entry <> ( "Mike" , "A" ); Entry < String , Integer > mark = new Entry <> ( "Mike" , 100 );System.out.printf ( " grade : % s %n" , grade); System.out.printf ( " mark : % s % n " , mark ) ;Entry < Integer , Boolean > prime = new Entry <> ( 13 , true ) ; if ( prime.getValue ()) { System.out.println ( " % s هو عدد أولي .%n" , prime.getKey ( ) ) ; } else { System.out.println ( " % s ليس عددًا أوليًا.%n" , prime.getKey ( ) ) ; }

لا يوجد ما يُسمى بمعامل المعين في لغات أخرى مشتقة من جافا مثل C# أو Kotlin ، والتي لديها طرقها الخاصة لتجنب معلومات النوع الزائدة. بينما يوجد شيء مشابه بصريًا في C++ ، إلا أنه لا يدل على استنتاج مُعامل النوع، بل يشير فقط إلى مُعامل النوع الافتراضي.

template < typename T = int > class Box { // ... };Box <> v ; // يشير إلى Box<int>

اكتب الأحرف البديلة

لا يقتصر وسيط النوع للأنواع المُعَلمة على فئة أو واجهة محددة. تسمح لغة جافا باستخدام "أحرف البدل" كوسائط للأنواع المُعَلمة. تأتي أحرف البدل على شكل " <?>"؛ مع إمكانية تحديد حد أعلى أو أدنى . ونظرًا لعدم معرفة النوع الدقيق الذي يمثله حرف البدل، تُفرض قيود على أنواع الدوال التي يمكن استدعاؤها على كائن يستخدم الأنواع المُعَلمة.

java.util.Collection<E>فيما يلي مثال حيث يتم تحديد نوع العنصر a باستخدام حرف بدل:

استيراد java.util.ArrayList ؛ استيراد java.util.Collection ؛Collection <?> c = new ArrayList <String> ( ) ; c.add ( new Object ( )); // خطأ في وقت الترجمة c.add ( null ) ; // مسموح به

بما أننا لا نعرف نوع العنصر الذي cيمثله، فلا يمكننا إضافة كائنات إليه. add()تأخذ الدالة وسائط من النوع E، وهو نوع العنصر في Collection<E>الواجهة العامة. عندما يكون وسيط النوع الفعلي ?، فإنه يمثل نوعًا غير معروف. أي قيمة وسيط نمررها إلى الدالة add()يجب أن تكون نوعًا فرعيًا من هذا النوع غير المعروف. ولأننا لا نعرف ما هو هذا النوع، فلا يمكننا تمرير أي قيمة إليه. الاستثناء الوحيد هو القيمة الفارغة (null )؛ وهي عنصر من كل نوع. [ 12 ]

لتحديد الحد الأعلى لنوع عام، تُستخدم الكلمة المفتاحية للإشارة إلى أن وسيط النوع هو نوع فرعي من الفئة المحددة. [ 13 ] وهذا يعني أن القائمة المعطاة تحتوي على كائنات من نوع غير معروف يمتد من الفئة. على سبيل المثال، يمكن أن تكون القائمة `<n>` أو `<n> `. قراءة عنصر من القائمة ستُرجع `<n>` . إضافة عناصر فارغة مسموح بها أيضًا. [ 14 ]extendsList<?extendsNumber>NumberList<Float>List<Number>Number

يُضفي استخدام الأحرف البديلة أعلاه مرونةً [ 13 إذ لا توجد علاقة وراثية بين أي نوعين مُعاملين بنوع مُحدد كمعامل نوع. لا يُعد أيٌّ من النوعين List<Number>نوعًا List<Integer>فرعيًا للآخر، على الرغم من أن النوع الفرعي من النوع الأول java.lang.Integerهو نوع فرعي من النوع الثاني java.lang.Number. [ 13 ] لذا، فإن أي دالة تأخذ List<Number>النوع الأول كمعامل لا تقبل وسيطًا من النوع الأول List<Integer>. لو كان الأمر كذلك، لأمكن إدخال نوع java.lang.Numberليس من النوع الأول java.lang.Integerفيها، مما يُخالف سلامة النوع. إليك مثال يُوضح كيف ستُخالف سلامة النوع إذا List<Integer>كان النوع الأول نوعًا فرعيًا من النوع الثاني List<Number>:

استيراد java.util.ArrayList ؛ استيراد java.util.List ؛List <Integer> intList = new ArrayList <> ( ); intList.add(2); List <Number> nums = intList ; // صحيح إذا كانت List <Integer> نوعًا فرعيًا من List<Number> وفقًا لقاعدة الاستبدال. nums.add ( 3.14 ); Integer x = intList.get ( 1 ) ; // الآن تم تعيين 3.14 لمتغير من نوع Integer !

الحل باستخدام الأحرف البديلة ينجح لأنه يمنع العمليات التي من شأنها أن تنتهك سلامة النوع:

استيراد java.util.List ;List <? extends Number > nums = ints ; // صحيح nums.add ( 3.14 ); // خطأ في وقت الترجمة nums.add ( null ) ; // مسموح

لتحديد الحد الأدنى لفئة نوع ما، superتُستخدم الكلمة المفتاحية `<type>`. تشير هذه الكلمة المفتاحية إلى أن وسيط النوع هو نوع فائق للفئة المُحدِّدة. لذا، يمكن أن يُمثِّل ` <type>` أو `<type> `. تُعيد القراءة من قائمة مُعرَّفة كـ ` <type>` عناصر من النوع `<type>` . تتطلب الإضافة إلى هذه القائمة إما عناصر من النوع `<type>` ، أو أي نوع فرعي من `<type>` ، أو قيمة فارغة (وهي عنصر من كل نوع `<type>`).List<?superNumber>List<Number>List<Object>List<?superNumber>ObjectNumberNumber

تُقدّم الاختصارات PECS (المنتج يمتد، المستهلك فائق) من كتاب Effective Java لجوشوا بلوخ طريقة سهلة لتذكر متى يجب استخدام الأحرف البديلة (المقابلة للتغاير والتغاير العكسي ) في لغة جافا. [ 13 ]

الأنواع العامة في عبارة throws

على الرغم من أن الاستثناءات نفسها لا يمكن أن تكون عامة، إلا أن معلمات النوع يمكن أن تظهر في عبارة throws:

public < T extends Throwable > void throwMeConditional ( boolean conditional , T exception ) throws T { if ( conditional ) { throw exception ; } }

في هذه الحالة، يكون ذلك ممكناً لأن معلمة النوع محدودة من الأسفل بواسطة java.lang.Throwable، مما يضمن Tإمكانية ظهورها في throwsالعبارة.

مشاكل في مسح النوع

يتم التحقق من صحة الأنواع العامة أثناء الترجمة. [ 8 ] ثم تُزال معلومات النوع العام في عملية تُسمى محو النوع . [ 7 ] على سبيل المثال، سيتم تحويلها إلى النوع غير العام ، الذي يحتوي عادةً على كائنات عشوائية. يضمن التحقق أثناء الترجمة أن الكود الناتج يستخدم النوع الصحيح. [ 8 ]List<Integer>List

بسبب حذف النوع، لا يمكن تحديد معلمات النوع أثناء التشغيل. [ 7 ] على سبيل المثال، عند ArrayListفحص عنصر ما أثناء التشغيل، لا توجد طريقة عامة لتحديد ما إذا كان، قبل حذف النوع، عنصرًا من نوع معين ArrayList<Integer>أو عنصرًا من نوع آخر ArrayList<Float>. يشعر الكثيرون بالاستياء من هذا القيد. [ 15 ] توجد طرق جزئية. على سبيل المثال، يمكن فحص العناصر الفردية لتحديد النوع الذي تنتمي إليه؛ على سبيل المثال، إذا كان العنصر java.util.ArrayList<E>يحتوي على عنصر من نوع معين java.lang.Integer، فقد يكون هذا العنصر java.util.ArrayList<E>قد تم تحديد معلماته باستخدام النوع Integer(ومع ذلك، قد يكون قد تم تحديد معلماته باستخدام أي عنصر أب من النوع الآخر java.lang.Integer، مثل النوع الأول java.lang.Numberأو java.lang.Objectالنوع الثاني).

ولتوضيح هذه النقطة، فإن الكود التالي يُخرج "متساوي":

استيراد java.util.ArrayList ؛ استيراد java.util.List ؛List <Integer> li = new ArrayList <> ( ) ; List <Float> lf = new ArrayList < > ( ) ; if ( li.getClass ( ) == lf.getClass ( ) ) { // النتيجة صحيحة System.out.println ( " Equal " ) ; }

ومن الآثار الأخرى لمحو النوع أن الفئة العامة لا يمكنها توسيع java.lang.Throwableالفئة بأي شكل من الأشكال، بشكل مباشر أو غير مباشر: [ 16 ]

// يتسبب في خطأ في الترجمة public class GenericException < T > extends Exception { // ... }

السبب في عدم دعم هذا الأمر هو حذف النوع:

حاول { ارمِ استثناءً عامًا من النوع < عدد صحيح > ( ); } أمسك ( استثناء عام من النوع < عدد صحيح > e ) { System.err.println ( " عدد صحيح" ) ; } أمسك ( استثناء عام من النوع < سلسلة نصية > e ) { System.err.println ( " سلسلة نصية " ) ; }

بسبب حذف النوع، لن يعرف وقت التشغيل أي كتلة catch يجب تنفيذها، لذلك فإن هذا محظور من قبل المترجم.

تختلف الأنواع العامة في جافا عن قوالب C++ . تُنتج الأنواع العامة في جافا نسخة مُجمّعة واحدة فقط من الفئة أو الدالة العامة، بغض النظر عن عدد أنواع المعاملات المُستخدمة. علاوة على ذلك، لا تحتاج بيئة تشغيل جافا إلى معرفة نوع المعامل المُستخدم، لأن معلومات النوع تُتحقق منها أثناء التجميع ولا تُضمّن في الكود المُجمّع. بالتالي، يستحيل إنشاء نسخة من فئة جافا من نوع مُعامل، لأن الإنشاء يتطلب استدعاء دالة البناء، وهي غير متاحة إذا كان النوع غير معروف.

على سبيل المثال، لا يمكن تجميع الكود التالي:

استيراد java.util.List ;<T> T instantiateElementType ( List <T> arg ) { return new T (); // يتسبب في خطأ في الترجمة }

نظرًا لوجود نسخة واحدة فقط لكل فئة عامة أثناء التشغيل، فإن المتغيرات الثابتة تُشارك بين جميع نسخ الفئة، بغض النظر عن مُعامل النوع الخاص بها. وبالتالي، لا يُمكن استخدام مُعامل النوع في تعريف المتغيرات الثابتة أو في الدوال الثابتة.

تم تطبيق محو النوع في جافا للحفاظ على التوافق مع الإصدارات السابقة من البرامج المكتوبة قبل جافا SE5. [ 8 ]

الاختلافات عن المصفوفات

توجد عدة اختلافات مهمة بين المصفوفات (سواء المصفوفات الأولية أو المصفوفات العامة) والأنواع العامة في لغةjava.lang.Object جافا. ومن أبرز هذه الاختلافات، الاختلافات المتعلقة بالتباين والتجسيد .

التغاير، والتغاير العكسي، والثبات

الأنواع العامة ثابتة، بينما المصفوفات متغيرة . [ 7 ] هذه ميزة لاستخدام الأنواع العامة مقارنةً بالكائنات غير العامة مثل المصفوفات. [ 7 ] على وجه التحديد، يمكن للأنواع العامة أن تساعد في منع استثناءات وقت التشغيل عن طريق طرح استثناء وقت الترجمة لإجبار المطور على إصلاح الكود.

على سبيل المثال، إذا قام مطور بتعريف java.lang.Object[]كائن ثم أنشأ نسخة منه ككائن جديد java.lang.Long[]، فلن يُثار أي استثناء أثناء الترجمة (لأن المصفوفات متغيرة). [ 7 ] قد يُعطي هذا انطباعًا خاطئًا بأن الكود مكتوب بشكل صحيح. مع ذلك، إذا حاول المطور إضافة عنصر java.lang.Stringإلى هذا java.lang.Long[]الكائن، فسيُثير البرنامج استثناءً java.lang.ArrayStoreException. [ 7 ] يمكن تجنب هذا الاستثناء أثناء التشغيل تمامًا إذا استخدم المطور الأنواع العامة.

إذا قام المطور بتعريف Collection<Object>كائن ثم أنشأ نسخة جديدة منه بنوع إرجاع ArrayList<Long>، فسيُصدر مُصرّف جافا (بشكل صحيح) استثناءً أثناء وقت الترجمة للإشارة إلى وجود أنواع غير متوافقة (لأن الأنواع العامة ثابتة). [ 7 ] وبالتالي، يتم تجنب استثناءات وقت التشغيل المحتملة. يمكن حل هذه المشكلة بإنشاء نسخة من الكائن Collection<Object>باستخدام ArrayList<Object>كائن آخر. بالنسبة للتعليمات البرمجية التي تستخدم Java SE7 أو الإصدارات الأحدث، Collection<Object>يمكن إنشاء ArrayList<>الكائن باستخدام عامل التشغيل الماسي (--).

التجسيد

تُجسّد المصفوفات ، أي أن كائن المصفوفة يفرض معلومات نوعه أثناء التشغيل، بينما لا تُجسّد الأنواع العامة في جافا. [ 7 ] وذلك لأن المصفوفات هي فئات حقيقية يُنشئها المُصرّف في آلة جافا الافتراضية؛ فلكل نوع T، يوجد نوع آخر T[].

بصورة أدق، تُعتبر الكائنات ذات النوع العام في جافا أنواعًا غير قابلة للتجسيد. [ 7 ] النوع غير القابل للتجسيد هو نوع يحتوي تمثيله في وقت التشغيل على معلومات أقل من تمثيله في وقت الترجمة. [ 7 ]

الكائنات ذات النوع العام في جافا غير قابلة للتجسيد بسبب حذف النوع. [ 7 ] تفرض جافا معلومات النوع فقط في وقت الترجمة. بعد التحقق من معلومات النوع في وقت الترجمة، يتم تجاهلها، ولن تكون معلومات النوع متاحة في وقت التشغيل. [ 7 ]

تشمل أمثلة الأنواع غير القابلة للتجسيد List<T>و List<String>، حيث Tيمثل معاملًا رسميًا عامًا. [ 7 ]

مشروع حول الأدوية الجنيسة

مشروع فالهالا هو مشروع تجريبي يهدف إلى تطوير ميزات اللغة والأنواع العامة في جافا، وذلك للإصدارات المستقبلية بدءًا من جافا 10 فصاعدًا. تشمل التحسينات المحتملة ما يلي: [ 17 ]

انظر أيضاً

الاقتباسات

  1. لغة برمجة جافا
  2. يمكن طرح استثناء ClassCastException حتى في حالة عدم وجود تحويلات أو قيم فارغة. "أنظمة أنواع Java وScala غير سليمة" (ملف PDF) .
  3. بلوخ 2018 ، الصفحات 123-125، الفصل §5 البند 27: إزالة التحذيرات غير المدققة.
  4. GJ: جافا العامة
  5. مواصفات لغة جافا، الطبعة الثالثة، بقلم جيمس جوسلينج، وبيل جوي، وجاي ستيل، وجيلاد براخا - برنتيس هول بي تي آر 2005
  6. شركة أوراكل (6 يونيو 2026). "Interface PrimitiveIterator<T,T_CONS>" . docs.oracle.com . شركة أوراكل.
  7. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Bloch 2018 ، ص 126-129 ، الفصل §5 البند 28: تفضيل القوائم على المصفوفات.
  8. 1 2 3 4 5 6 7 8 Bloch 2018 ، ص 117-122 ، الفصل §5 البند 26: لا تستخدم الأنواع الخام.
  9. بلوخ 2018 ، ص 135-138، الفصل §5 البند 30: تفضيل الأساليب العامة.
  10. جلعاد براخا (5 يوليو 2004). "الأنواع العامة في لغة برمجة جافا" (ملف PDF) . www.oracle.com .
  11. "استنتاج النوع لإنشاء مثيل عام" .
  12. جلعاد براخا (5 يوليو 2004). "الأنواع العامة في لغة برمجة جافا" (ملف PDF) . www.oracle.com . ص 5. 
  13. 1 2 3 4 Bloch 2018 ، ص 139-145 ، الفصل §5 البند 31: استخدم الأحرف البديلة المحدودة لزيادة مرونة واجهة برمجة التطبيقات.
  14. براخا، جلعاد . "الرموز البديلة > المكافأة > الأنواع العامة" . دروس جافا™ التعليمية . أوراكل. ...الاستثناء الوحيد هو القيمة الفارغة (null)، وهي عنصر من عناصر كل نوع...
  15. جافتر، نيل (2006-11-05). "الأنواع العامة المُجسّدة للغة جافا" . تم الاسترجاع في 2010-04-20 .
  16. "مواصفات لغة جافا، القسم 8.1.2" . أوراكل . تم الاطلاع عليه بتاريخ 24 أكتوبر 2015 .
  17. غوتز، برايان. "مرحباً بكم في فالهالا!" . أرشيف بريد OpenJDK . OpenJDK . تم الاطلاع عليه بتاريخ 12 أغسطس 2014 .

مراجع

  • بلوخ، جوشوا (2018). "جافا الفعّالة: دليل لغة البرمجة" (  الطبعة الثالثة). أديسون-ويسلي. ISBN 978-0134685991.