Java Generics: תיאור ושיטות
מאז הופעתה של שפת ג 'אווה עברהרבה שינויים, אשר, ללא ספק, הביא רגעים חיוביים הפונקציונליות שלו. שינוי אחד משמעותי כזה הוא המבוא של Java Generic או הכללה. פונקציונליות זו הפכה את השפה לא רק גמישה יותר צדדי, אלא גם הרבה יותר בטוח במונחים של צמצום סוגי נתונים.
העובדה היא כי לפני כניסתה של גנריות גנריותקוד ב- Java ניתן ליצור רק על ידי התייחסות לסוג אובייקט. קישורים אלה ניתן להקצות לכל אובייקט. אחרי הכל, כל השיעורים ב- Java הם צאצאי משתמע של מעמד האובייקט. עם זאת, גישה זו היא מקור פוטנציאלי של שגיאות בטיחות מסוג רבות בעת המרת אובייקט מפורש מאובייקט לסוג היעד. כאשר נעשה שימוש בהכללות, כל הטלסקופים מבוצעים במרומז ובאופן אוטומטי, אשר מונע אפילו את האפשרות של שגיאות להתרחש.
Java Generics: תיאור ודוגמה
הבה ניקח דוגמה פשוטה להחלת הכללה על המעמד הרגיל בתרשים שלהלן. ורק אז נמשיך לבדיקה מפורטת של כל הדקויות וניואנסים של Java Generic.
שימו לב איךזוג הכרזה בכיתה. מיד לאחר מעמד שם, בסוגריים זוויתיים פתוח, אשר הצביע על מכתב ט זה הוא סוג של מילוי, אשר נמצאת בתהליך של יצירת מופע של מחלקה זו יוחלפו על ידי סוג מסוים. זה נראה כדלקמן: זוג <Integer> obj = זוג חדש <Integer> (). יצוין כי במקום T יכול לציין כל מכתב, אבל, ככלל, להשתמש T, V או E.
הערה: החל עם הגירסה השמינית של Java, המפרטת את סוג היעד בהכרזותיו בסוגריים זוויתיים התיחסות בנאי ניתן להשאיר ריק. אז למשל ניתן לשכתב כאמור: זוג <Integer> obj = חדש זוג <> ().
כאשר מחלקה היא הכריזה בדרך זו, ולאחר מכן שלהניתן להשתמש במכתב זה במקום בסוגי שדה ספציפיים, בהתייחסויות ובשיטות המוחזרות בשיטות. מכיוון ש- T מוחלף על-ידי סוג מסוים בעת יצירת אובייקט מחלקה, השדות הראשונים והשניים במקרה זה יהיו מסוג שלם.
בעקבות ההיגיון, הטיעונים הראשונים-עבר את הבנאי המתאים, חייב להיות גם של מספר שלם או subclass שלה. אם תנסה להעביר סוג נתונים שונה ממה שצוין בעת יצירת האובייקט, המהדר לא ידלג על שגיאה זו. לכן, בנאי עם טיעונים בעת יצירת האובייקט יהיה הטופס הבא: זוג <שלם> obj = זוג חדש <> (מספר שלם חדש (1), מספר שלם חדש (2)). כך גם לגבי הטיעונים לשיטות setFirst ו- setSecond. וכפי שאתה כנראה כבר לנחש, getFirst ו getececond השיטות יחזיר ערכים מסוג שלם.
מעמד גנרי עם מספר פרמטרים
בכיתות גנריות, אתה יכול גם להכריז על מספר פרמטרים סוג שצוין בסוגריים זווית מופרדים על ידי פסיקים. הכיתה זוג במקרה זה מוצג באיור להלן.
כפי שניתן לראות, בעת יצירת מופע של מחלקה כזובסוגריים זווית, עליך לציין את אותו מספר סוגים כמו הפרמטרים. אם אתה מכיר כזה סוג של מבנה נתונים כמו מפה, אז אתה עשוי להבחין כי אותו עיקרון משמש שם. שם הטיעון הראשון קובע את סוג המפתח, והשני - סוג הערך. יש לציין כי סוגי הטיעונים שהועברו ליצירת האובייקט יכולים להיות זהים. לכן, ההצהרה הבאה של מופע של הכיתה זוג היא נכונה לחלוטין: זוג <מחרוזת, מחרוזת> obj.
כמה תכונות של הכללות
לפני שתמשיך הלאה, יש לציין כיהמהדר של Java אינו יוצר גרסאות שונות של המחלקה Pair. למעשה, במהלך תהליך הידור, כל המידע על הסוג הגנרי נמחק. במקום זאת, הטיפוסים המתאימים יצוקים, ויוצרים גרסה מיוחדת של המחלקה Pair. עם זאת, התוכנית עצמה עדיין יש גרסה אחת כללית של מחלקה זו. תהליך זה נקרא ניקוי ג 'אווה סוג כללי.
בואו נציין נקודה חשובה. הפניות לגרסאות שונות של אותה המחלקה הגנרית של Java אינן יכולות להצביע על אותו אובייקט. כלומר, נניח שיש לנו שני קישורים: Pair <Integer> obj1 ו- Pair <Double> obj2. לכן, מתרחשת שגיאה בשורה obj1 = obj2. למרות ששני המשתנים הם מסוג Pair <T>, האובייקטים שהם מתייחסים אליהם שונים. זוהי דוגמה חיה לביטחון הסוגים ב- Java Generic.
הגבלות המוטלות על מעמדות כלליים
חשוב לדעת כי הכללות ניתן ליישםרק לסוגי ייחוס, כלומר, הוויכוח שהועבר לארגומנט java של הפרמטר ברמה הגנרית חייב להיות סוג מחלקה. סוגים פשוטים כמו, למשל, כפול או ארוך, לא ניתן להעביר. במילים אחרות, השורה הבאה של הצהרת המחלקה Pair אינה תקפה: Pair <int> obj. עם זאת, הגבלה זו אינה בעיה רצינית, שכן Java יש בכיתה עטיפה המקביל עבור כל סוג פרימיטיבי. למען הדיוק, אם אתה רוצה לתמצת מספר שלם וערך לוגי בכיתה, חבילת Auto תעשה הכל בשבילך: זוג <שלם, בוליאני> obj = זוג חדש <> (25, נכון).
מגבלה רצינית נוספת היאחוסר אפשרות ליצור מופע של פרמטר סוג. לכן, השורה הבאה תגרום לשגיאת קומפילציה: T הראשון = T חדש (). זה ברור, כי אתה לא יודע מראש אם מעמד מלא או ממשק מופשט יועברו כטיעון. כנ"ל לגבי יצירת מערכים.
סוגים מוגבלים
לעתים קרובות יש מצביםיש להגביל את רשימת סוגי זה יכול להיות מועבר כארגומנט למחלקה הגנרית ג 'אווה. נניח כי בכיתה זוג שלנו אנחנו רוצים לתמצת ערכים מספריים בלבד עבור פעולות מתמטיות נוספות עליהם. כדי לעשות זאת, אנחנו צריכים להגדיר את הגבול העליון של פרמטר סוג. זה מיושם באמצעות הצהרת superclass בירושה על ידי כל הטיעונים שהועברו בסוגריים זווית. זה ייראה כך: Class Pair <T משתרע מספר>. בדרך זו, מהדר לומד כי במקום פרמטר T, אתה יכול להחליף את מחלקה מספר או אחד subclasses שלה.
זוהי טכניקה נפוצה. הגבלות כאלה משמשות לעתים קרובות כדי להבטיח תאימות של פרמטרים סוג באותה המחלקה. שקול דוגמה על המחלקה זוג שלנו: מחלקה זוג <T, V מרחיב T>. כאן אנו אומרים מהדר כי סוג T יכול להיות שרירותי, וסוג V חייב להיות גם סוג או אחד subclasses שלה.
ההגבלה "מלמטה" מתרחשת בדיוק אותו דבראבל במקום שהמילה מתפשטת, המילה סופר נכתבת. כלומר, הצהרת המעמד Pair <T Super ArrayList> מציינת שבמקום T, ניתן להחליף את ArrayList או כל סוג או ממשק שהוא יורש.
שיטות ג 'אווה גנריות ובנאים
ב Java הכללות ניתן ליישם לא רק לגבי הכיתות, אלא גם שיטות. לכן, השיטה הכללה יכולה להיות מוצהרת בכיתה רגילה.
כפי שניתן לראות בתרשים לעיל, אין שום דבר מסובך בהכרזה על השיטה הכללית. זה מספיק לשים סוגריים זווית לפני שיטת סוג לחזור ולציין פרמטרים סוג בהם.
במקרה של הבנאי, הכל נעשה באותו אופן:
סוגריים זווית במקרה זה ממוקמים לפני שם הבנאי, שכן הוא אינו מחזיר שום ערך. התוצאה של העבודה של שתי התוכניות תהיה:
מספר שלם
מחרוזת