JavaRush /בלוג Java /Random-HE /ספירות ב-Java (Java enum)
articles
רָמָה

ספירות ב-Java (Java enum)

פורסם בקבוצה
בעת התכנות, אנו נתקלים לעתים קרובות בצורך להגביל את סט הערכים התקפים עבור סוג נתונים מסוים. אז, למשל, ליום בשבוע יכולים להיות 7 ערכים שונים, לחודש בשנה יכולים להיות 12, ולעונה יכולה להיות 4. כדי לפתור בעיות כאלה, שפות תכנות רבות עם הקלדה סטטית מספקות סוג נתונים מיוחד - ספירה ( enum). ספירה לא הופיעה ב-Java מיד. מבנה שפה מיוחד enumהוצג החל מגרסה 1.5. עד לנקודה זו, מתכנתים השתמשו בשיטות אחרות כדי ליישם ספירות. ספירות ב-Java (java enum) - 1

בניית אנדום

נתחיל עם דוגמה. נתאר enumאת סוג הנתונים לאחסון העונה באמצעות:
enum Season { WINTER, SPRING, SUMMER, AUTUMN }
ובכן, דוגמה פשוטה לשימוש בו:
Season season = Season.SPRING;
if (season == Season.SPRING) season = Season.SUMMER;
System.out.println(season);
כתוצאה מכך SUMMER יודפס לקונסולה . אני חושב שהדוגמה ברורה ואינה זקוקה להסבר.

Enum היא כיתה

על ידי הצהרה enum, אנו יוצרים באופן מרומז מחלקה הנגזרת מ- java.lang.Enum. באופן קונבנציונלי, הבנייה enum Season { ... }שווה ערך ל class Season extends java.lang.Enum { ... }. ולמרות שהמהדר לא מאפשר לנו לרשת מאיתנו במפורש java.lang.Enum, עדיין קל לאמת enumשהוא עבר בירושה באמצעות reflection:
System.out.println(Season.class.getSuperclass());
הדברים הבאים יוצגו במסוף:
class java.lang.Enum
הירושה בפועל מבוצעת עבורנו אוטומטית על ידי מהדר Java. לאחר מכן, בואו נסכים לקרוא למחלקה שנוצרה על ידי המהדר כדי ליישם את הספירה בשם enum-class, ואת הערכים האפשריים מהסוג המצוין כאלמנטים enum-a.

איברי Enum הם מופעים enumשל -class הנגישים סטטית

אלמנטים enum Season (WINTER, SPRING и т.д.)הם מופעים נגישים סטטית enumשל המחלקה Season. הזמינות הסטטית שלהם מאפשרת לנו לבצע השוואות באמצעות אופרטור השוואת הפניות ==. דוגמא:
Season season = Season.SUMMER;
if (season == Season.AUTUMN) season = Season.WINTER;

שם ומספר סידורי של אלמנט ה-enum

כפי שהוזכר קודם לכן, כל enumמחלקה יורשת java.lang.Enum, שמכילה מספר שיטות שימושיות עבור כל הספירות. דוגמא:
Season season = Season.WINTER;
System.out.println("season.name()=" + season.name() + " season.toString()=" + season.toString() + " season.ordinal()=" + season.ordinal());
הפלט יהיה:
season.name()=WINTER season.toString()=WINTER season.ordinal()=0
השיטות name(), toString()ומוצגות כאן ordinal(). הסמנטיקה של השיטות ברורה. יש לציין ששיטות אלו enumעוברות בירושה מהמחלקה java.lang.Enum. קבלת אלמנט enumלפי ייצוג המחרוזת של שמו. לעתים קרובות מתעוררת המשימה של קבלת אלמנט enumלפי ייצוג המחרוזת שלו. למטרות אלו, בכל enumמחלקה, המהדר יוצר אוטומטית שיטה סטטית מיוחדת: public static EnumClass valueOf(String name), המחזירה אלמנט ספירה EnumClassעם שם השווה ל name. דוגמה לשימוש:
String name = "WINTER";
Season season = Season.valueOf(name);
כתוצאה מביצוע הקוד, משתנה העונה יהיה שווה ל- Season.WINTER. שים לב שאם האלמנט לא נמצא, ייזרק IllegalArgumentException , ואם הוא nameשווה null, ייזרק NullPointerException . אגב, זה נשכח לעתים קרובות. מסיבה כלשהי, רבים משוכנעים בתוקף שאם פונקציה לוקחת ארגומנט אחד ובתנאים מסוימים זורקת IllegalArgumentException , אז כשמעבירים אותו לשם , nullבוודאי ייזרק גם IllegalArgumentException . אבל זה מעבר לעניין. בוא נמשיך. קבלת כל המרכיבים של ספירה לפעמים אתה צריך לקבל רשימה של כל האלמנטים enumשל -class בזמן ריצה. למטרות אלו, enumהמהדר יוצר שיטה בכל-class public static EnumClass[] values(). דוגמה לשימוש:
System.out.println(Arrays.toString(Season.values()));
אנו מקבלים את הפלט הבא:
[WINTER, SPRING, SUMMER, AUTUMN]
שימו לב שלא שיטה valueOf()ולא מתודה values()מוגדרות במחלקה java.lang.Enum. במקום זאת, הם מתווספים אוטומטית על ידי המהדר כאשר enumה--class מורכבת. הוספת שיטות משלך ל-- enumclass יש לך הזדמנות להוסיף שיטות משלך הן ל- enumclass והן לאלמנטים שלה: ספירות ב-Java (Java enum) - 2אותו הדבר, אבל עם פולימורפיזם: ספירות ב-Java (Java enum) - 3הדוגמה האחרונה מדגימה את השימוש בירושה ב- enum. עוד על כך בהמשך. ירושהenum ב- Java enumמאפשרת ליישם היררכיית מחלקות, שהאובייקטים שלה נוצרים במופע בודד ונגישים סטטית. במקרה זה, אלמנטים enumיכולים להכיל בנאים משלהם. בוא ניתן דוגמה: ספירות ב-Java (Java enum) - 4כאן אנו מכריזים על ספירה Typeעם שלושה אלמנטים INT, INTEGERו STRING. המהדר יצור את המחלקות והאובייקטים הבאים:
  • Type- כיתה נגזרת מjava.lang.Enum
  • INT- אובייקט של מחלקה 1 נגזרType
  • INTEGER- אובייקט של מחלקה 2 נגזרType
  • STRING- אובייקט של כיתה 3 נגזרType
שלוש מחלקות נגזרות ייווצרו עם שיטה Object parse(String)ובנאי פולימורפית Type(..., boolean). יחד עם זאת, אובייקטים של מחלקות INT, INTEGERוקיימים STRINGבעותק בודד ונגישים סטטית. אתה יכול לאמת את זה:
System.out.println(Type.class);
System.out.println(Type.INT.getClass() + " " + Type.INT.getClass().getSuperclass());
System.out.println(Type.INTEGER.getClass() + " " + Type.INTEGER.getClass().getSuperclass());
System.out.println(Type.STRING.getClass()  + " " + Type.STRING.getClass().getSuperclass());
אנו מקבלים את הפלט הבא:
class Type
class Type$1 class Type
class Type$2 class Type
class Type$3 class Type
ניתן לראות שהמהדר יצר מחלקה Typeו-3 nestedמחלקות שנגזרו מ- Type.

פירוק ה-enum-class עם ירושה

כדי לאשר את האמור לעיל, אנו מציגים גם את התוצאה של פירוק הספירה Typeמהדוגמה לעיל: ספירות ב-Java (Java enum) - 5

ספירות ופולימורפיזם פרמטרי

הקורא עשוי לתהות: " מדוע ספירת הסוגים לעיל אינה משתמשת בגנריות? " העובדה היא שב-Java השימוש בגנריות enumאסור. אז הדוגמה הבאה לא תתאים:
enum Type<T> {}

מחקר נוסף

להבנה מעמיקה יותר של אופן הפעולה של ספירות ב-Java, אני ממליץ לך להכיר את קוד המקור של הכיתה java.lang.Enum, ולהשתמש גם במפרקת Jad כדי ללמוד את הקוד שנוצר. יתרה מכך, לימוד קוד המקור של ספריית Java הוא הכרחי לחלוטין כדי להבין כמה מהמנגנונים ב-Java פועלים והוא שימושי כאסמכתא לעיצוב מונחה עצמים. קישור למקור המקורי: http://alexander.lds.lg.ua/
הערות
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION