Java Generics - לעומת

1. סקירה כללית

במדריך מהיר זה נראה את דמיון והבדלים בין ו ב- Java Generics.

עם זאת, זהו נושא מתקדם, חובה לקבל הבנה בסיסית בנושא לפני שנצלול לעיקר העניין.

2. רקע של גנריות

גנריות הוצגו ב- JDK 5 בכדי למנוע שגיאות זמן הידור ולחזק את בטיחות הסוגים. בטיחות נוספת מסוג זה מבטלת יציקה במקרים מסוימים של שימוש ומאפשרת למתכנתים לכתוב אלגוריתמים כלליים, שניהם יכולים להוביל לקוד קריא יותר.

לדוגמא, לפני JDK 5, נצטרך לעבוד עם רכיבי הרשימה באמצעות ליהוק. זה, בתורו, יצר סוג מסוים של שגיאות זמן ריצה:

רשימה aList = ArrayList חדש (); aList.add (מספר שלם חדש (1)); aList.add ("a_string"); עבור (int i = 0; i <aList.size (); i ++) {Integer x = (Integer) aList.get (i); }

כעת, לקוד זה יש שתי בעיות שברצוננו לטפל בהן:

  • אנחנו צריכים צוות שחקנים מפורש כדי לחלץ מהם ערכים רשימה - הסוג תלוי בסוג המשתנה משמאל - מספר שלם במקרה הזה
  • נקבל שגיאת זמן ריצה באיטרציה השנייה כשאנחנו מנסים להעביר מחרוזת ל מספר שלם

גנריות ממלאות את התפקיד עבורנו:

רשימת iList = ArrayList חדש (); iList.add (1); iList.add ("a_string"); // הידור שגיאת זמן עבור (int i = 0; i <iList.size (); i ++) {int x = iList.get (i); } 

המהדר יגיד לנו שאי אפשר להוסיף מחרוזת אל א רשימה מהסוג מספר שלם, וזה טוב יותר מאשר לגלות בזמן הריצה.

יתר על כן, אין צורך בליהוק מפורש מכיוון שהמהדר כבר יודע זאת iList מחזיק מספר שלםס. בנוסף, בגלל הקסם של ביטול אגרוף, אפילו לא היינו צריכים מספר שלם סוג, צורתו הפרימיטיבית מספיקה.

3. תווים כלליים בגנריקה

סימן שאלה, או תו כללי, משמש בגנריקה כדי לייצג סוג לא ידוע. זה יכול להיות בעל שלוש צורות:

  • כרטיסי בר ללא גבולות: רשימה מייצג רשימה מסוג לא ידוע
  • כרטיסי בר בעלי גבולות עליונים: רשימה מייצג רשימה של מספר או תת-הסוגים שלה כגון מספר שלם ו לְהַכפִּיל
  • כרטיסי בר מוגבלים תחתון: רשימה מייצג רשימה של מספר שלם או סוגי העל שלו מספר ו לְהִתְנַגֵד

עכשיו, מאז לְהִתְנַגֵד הוא סוג העל הטמון מכל הסוגים בג'אווה, היינו מתפתים לחשוב שהוא יכול לייצג גם סוג לא ידוע. במילים אחרות, רשימה ו רשימה יכול לשרת את אותה מטרה. אבל הם לא.

הבה נבחן את שתי השיטות הבאות:

ריק סטטי ציבורי printListObject (רשימת רשימה) {עבור (רכיב אובייקט: רשימה) {System.out.print (אלמנט + ""); }} חלל סטטי ציבורי printListWildCard (רשימת רשימות) {עבור (רכיב אובייקט: רשימה) {System.out.print (אלמנט + ""); }} 

ניתנה רשימה של מספר שלםs, תגיד:

רשימה li = Arrays.asList (1, 2, 3);

printListObject (li) לא יתכנס, ונקבל את השגיאה הזו:

השיטה printListObject (List) אינה חלה על הטיעונים (List)

ואילו printListWildCard (li) ירכיב ויצא 1 2 3 לקונסולה.

4. ו - הדימיון

בדוגמה שלעיל, אם נשנה את חתימת השיטה עבור printListWildCard ל:

public static void printListWildCard (רשימת רשימות)

זה יתפקד באותו אופן כמו printListWildCard (רשימת רשימות) עשה. זאת בשל העובדה ש לְהִתְנַגֵד הוא סוג-על של כל אובייקטים של Java, ובעצם הכל מתארך לְהִתְנַגֵד. אז, א רשימה שֶׁל מספר שלםs גם מעובד.

בקצרה, זה אומר ש ? ו ? מרחיב את האובייקט הם שם נרדף בדוגמה זו.

בעוד שברוב המקרים זה יתקיים, אבל יש גם כמה הבדלים. בואו נסתכל עליהם בחלק הבא.

5. ו - ההבדל

טיפוסים הניתנים להחזרה הם כאלה שסוגם לא נמחק בזמן הקומפילציה. במילים אחרות, לייצוג זמן ריצה של סוג שאינו ניתן להחזרה יהיה פחות מידע מאשר מקבילו לזמן הידור, מכיוון שחלק ממנו יימחק.

ככלל, סוגים פרמטרים אינם ניתנים לתיקון מחדש. זה אומר רשימה ו מַפָּה אינם ניתנים לתיקון. המהדר מוחק את סוגם ומתייחס אליהם כאל רשימה ו מַפָּה בהתאמה.

היוצא מן הכלל היחיד לכלל זה הוא סוגי תווים כלליים בלתי מוגבלים. זה אומר רשימה ו מַפָּה ניתנים לתיקון.

מצד שני, רשימה אינו ניתן לתיקון. אמנם עדין, אך זהו הבדל בולט.

לא ניתן להשתמש בסוגים שאינם ניתנים לתיקון במצבים מסוימים כמו למשל ב- מופע של מפעיל או כאלמנטים של מערך.

אז אם נכתוב:

רשימת someList = ArrayList חדש (); מופע בוליאני = רשימת מופעים מסוימים של רשימה

קוד זה מהדר ו מופע מבחן הוא נָכוֹן.

אבל, אם אנו משתמשים ב- מופע של מפעיל רשימה:

רשימת AnotherList = ArrayList חדש (); מופע בוליאני = מופע אחר של רשימה;

ואז שורה 2 לא מתקבצת.

באופן דומה, בקטע הקוד שלמטה שורה 1 מהדרת, אך שורה 2 אינה:

רשימה [] arrayOfList = רשימה חדשה [1]; רשימה [] arrayOfAnotherList = רשימה חדשה [1]

6. מסקנה

במדריך קצר זה ראינו את הדמיון והשוני ו .

למרות שהם דומים בעיקר, ישנם הבדלים עדינים בין השניים מבחינת היותם ניתנים לתיקון או לא.


$config[zx-auto] not found$config[zx-overlay] not found