JavaRush /בלוג Java /Random-HE /אוטו-בוקסינג ו-unboxing ב-Java
DSergey_Kh
רָמָה

אוטו-בוקסינג ו-unboxing ב-Java

פורסם בקבוצה
במאמר זה נסתכל על תכונה בג'אווה הנקראת autoboxing/unboxing . Autoboxing ו- Unboxing הם פונקציה של המרת טיפוסים פרימיטיביים לסוגי אובייקטים ולהיפך. אוטו-בוקסינג ו-unboxing ב-Java - 1התהליך כולו מבוצע באופן אוטומטי על ידי Java Runtime Environment (JRE). אבל אתה צריך להיות זהיר בעת יישום פונקציה זו, כי... זה יכול להשפיע על הביצועים של התוכנית שלך.

מבוא

בגרסאות מתחת ל-JDK 1.5, לא היה קל להמיר סוגי נתונים פרימיטיביים כגון int, char, float, doubleלמחלקות העטיפה שלהם אינטגר, Character, Float, Double. החל מ-JDK 5, פונקציונליות זו, המרת טיפוסים פרימיטיביים לאובייקטים שווים, מיושמת באופן אוטומטי. מאפיין זה ידוע בשם Autoboxing . התהליך ההפוך, בהתאמה, הוא Unboxing , כלומר. תהליך המרת אובייקטים לסוגים הפרימיטיביים המתאימים להם. קוד לדוגמה עבור אוטו-בוקסינג ו-unboxing ניתן להלן: Autoboxing
Integer integer = 9;
Unboxing
int in = 0;
in = new Integer(9);
מתי משתמשים באריזה ופריקה אוטומטית? ה-Autoboxing משמש את מהדר Java בתנאים הבאים:
  • כאשר ערך מסוג פרימיטיבי מועבר למתודה כפרמטר מתודה, המצפה לאובייקט ממחלקת העטיפה המקבילה.
  • כאשר ערך מסוג פרימיטיבי מוקצה למשתנה של מחלקת העטיפה המתאימה.
שקול את הדוגמה הבאה: רישום 1: קוד פשוט המציג אגרוף אוטומטי
public int sumEvenNumbers(List<Integer> intList ) {
int sum = 0;
for (Integer i: intList )
if ( i % 2 == 0 )
sum += i;
return sum;
}
לפני jdk 1.5, הקוד שלמעלה היה גורם לשגיאת קומפילציה מכיוון שלא ניתן היה להחיל את האופרטור השארית % ו-unary plus += על מחלקת עטיפה. אבל ב-jdk 1.5 ומעלה הקוד הזה מתבצע קומפילציה ללא שגיאות, וממיר מספר שלם ל int. Unboxing משמש את מהדר Java בתנאים הבאים:
  • כאשר אובייקט מועבר כפרמטר למתודה המצפה לסוג פרימיטיבי מתאים.
  • כאשר אובייקט מוקצה למשתנה מהסוג הפרימיטיבי המתאים.
שקול את הדוגמה הבאה: רישום 2: קוד פשוט המציג unboxing
import java.util.ArrayList;
import java.util.List;

public class UnboxingCheck {

public static void main(String[] args) {
Integer in = new Integer(-8);

// 1. Распаковка через вызов метода
int absVal = absoluteValue(in);
System.out.println("absolute value of " + in + " = " + absVal);

List<Double> doubleList = new ArrayList<Double>();

// Автоупаковка через вызов метода
doubleList.add(3.1416);

// 2. Распаковка через присвоение
double phi = doubleList.get(0);
System.out.println("phi = " + phi);
}

public static int absoluteValue(int i) {
return (i < 0) ? -i : i;
}
}
Autoboxing ו- Unboxing מאפשרים למפתח לכתוב קוד קל לקריאה והבנה. הטבלה הבאה מציגה את סוגי הנתונים הפרימיטיביים ואת אובייקטי העטיפה המתאימים להם.
טיפוסים פרימיטיביים שיעורי מעטפת
בוליאני בוליאנית
בייט בייט
לְהַשְׁחִיר אופי
לָצוּף לָצוּף
int מספר שלם
ארוך ארוך
קצר קצר
טבלה 1: סוגים פרימיטיביים ומחלקות עטיפה מקבילות עם אופרטורים להשוואה ניתן להשתמש ב-Autoboxing ו- Unboxing עם אופרטורי השוואה. קטע הקוד הבא ממחיש כיצד זה קורה: רישום 3: קוד לדוגמה המציג אגרוף אוטומטי וביטול אריזה עם אופרטור השוואה
public class BoxedComparator {
  public static void main(String[] args) {
      Integer in = new Integer(25);
      if (in < 35)
          System.out.println("Value of int = " + in);
  }
}
אריזה ופירוק אוטומטית בעת העמסת שיטה אריזה ופריקה אוטומטית מתבצעת בעת העמסת יתר של שיטה המבוססת על הכללים הבאים:
  • הרחבה "מנצחת" אריזה במצב שבו יש בחירה בין הרחבה לאריזה, עדיפה הרחבה.
רישום 4: קוד לדוגמה המראה את היתרון של עומס יתר
public class WideBoxed {
  public class WideBoxed {
  static void methodWide(int i) {
       System.out.println("int");
   }

  static void methodWide( Integer i ) {
      System.out.println("Integer");
  }

  public static void main(String[] args) {
      short shVal = 25;
      methodWide(shVal);
  }
 }
}
פלט תוכנית - סוגint
  • הרחבה מנצחת מספר משתנה של ארגומנטים במצב בו היא הופכת לבחירה בין הרחבה למספר משתנה של ארגומנטים, הרחבה עדיפה.
רישום 5: קוד לדוגמה המראה את היתרון של עומס יתר
public class WideVarArgs {

    static void methodWideVar(int i1, int i2) {
      System.out.println("int int");
    }

    static void methodWideVar(Integer... i) {
       System.out.println("Integers");
    }

   public static void main( String[] args) {
       short shVal1 = 25;
      short shVal2 = 35;
     methodWideVar( shVal1, shVal2);
   }
  }
  • אריזה מנצחת מספר משתנה של ארגומנטים במצב בו היא הופכת לבחירה בין אריזה למספר משתנה של ארגומנטים, אריזה עדיפה.
רישום 6: קוד לדוגמה המראה את היתרון של עומס יתר
public class BoxVarargs {
     static void methodBoxVar(Integer in) {
         System.out.println("Integer");
     }

     static void methodBoxVar(Integer... i) {
         System.out.println("Integers");
     }
     public static void main(String[] args) {
         int intVal1 = 25;
         methodBoxVar(intVal1);
    }
}
עליך לזכור את הדברים הבאים בעת השימוש באריזה אוטומטית: כידוע, לכל תכונה טובה יש חסרון. אריזה אוטומטית אינה יוצאת דופן בהקשר זה. כמה הערות חשובות שעל מפתח לזכור בעת השימוש בתכונה זו:
  • השוואת אובייקטים עם ==האופרטור ' ' יכולה להיות מבלבלת, מכיוון שניתן להחיל אותה על טיפוסים ואובייקטים פרימיטיביים. כאשר אופרטור זה מוחל על אובייקטים, הוא למעשה משווה הפניות לאובייקטים, לא לאובייקטים עצמם.
רישום 7: קוד לדוגמה המציג את ההשוואה.
public class Comparator {
   public static void main(String[] args) {
     Integer istInt = new Integer(1);
       Integer secondInt = new Integer(1);

       if (istInt == secondInt) {
         System.out.println("both one are equal");

       } else {
          System.out.println("Both one are not equal");
      }
   }
}
  • ערבוב אובייקטים וטיפוסים פרימיטיביים עם אופרטורי השוויון והיחסים. אם נשווה טיפוס פרימיטיבי עם אובייקט, אז האובייקט אינו מקופס, מה שיכול לזרוק NullPointerExceptionאם האובייקט null.
  • שמירה במטמון של אובייקטים. השיטה valueOf()יוצרת מיכל של אובייקטים פרימיטיביים שהיא מאחסנת. מכיוון שערכים מאוחסנים במטמון בטווח -128 עד 127, כולל, האובייקטים המאוחסנים האלה עשויים להתנהג אחרת.
  • ירידה בביצועים. אחסון אוטומטי או unboxing פוגע בביצועי האפליקציה מכיוון שהוא יוצר אובייקט לא רצוי שמאלץ את אוסף האשפה לפעול בתדירות גבוהה יותר.
חסרונות של AutoBoxing למרות של AutoBoxing יש מספר יתרונות, יש לו את החסרונות הבאים: רשימה 8: קוד לדוגמה המראה את בעיית הביצועים.
public int sumEvenNumbers(List intList) {
          int sum = 0;
          for (Integer i : intList) {
              if (i % 2 == 0) {
                  sum += i;
              }
          }
         return sum;
   }
בחלק זה של הקוד, sum +=i הוא יורחב ל- sum = sum + i. החל מהאופרטור ' +', ה-JVM מתחיל לשחרר את הארגז מכיוון +שלא ניתן להחיל את האופרטור ' ' על אובייקט שלם. ואז התוצאה ארוזה אוטומטית בחזרה. לפני JDK 1.5, סוגי הנתונים intוהמספר השלם היו שונים. במקרה של עומס יתר בשיטה, נעשה שימוש בשני סוגים אלה ללא בעיות. עם כניסתה של אריזה/פריקה אוטומטית, הדבר נעשה קשה יותר. דוגמה לכך היא השיטה העמוסה remove()ב- ArrayList. למחלקה ArrayListיש שתי שיטות מחיקה - remove(index)ו- remove(object). במקרה זה, עומס יתר של השיטה לא יתרחש והשיטה המתאימה תיקרא עם הפרמטרים המתאימים.

סיכום

Autoboxing הוא מנגנון להמרה מרומזת של סוגי נתונים פרימיטיביים למחלקות עטיפה (אובייקטים) מתאימות. המהדר משתמש בשיטה valueOf()כדי להמיר טיפוסים פרימיטיביים לאובייקטים, ובשיטות וכו IntValue()' doubleValue()כדי להשיג את הטיפוסים הפרימיטיביים של האובייקט. אגרוף אוטומטי ממיר סוג בוליאני booleanלבוליאני, byteלבייט, charלתווים, floatלצוף, intלמספר שלם, longללונג, shortלקצר. הפריקה מתרחשת בכיוון ההפוך. מאמר מקורי
הערות
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION