ב-Java קיימים שני אזורי זיכרון עיקריים:
new נשמר בו.
Integer x = 10;
Integer a = new Integer(5);
כאשר רוצים להשוות ערכים של Integer, בדרך כלל נשתמש ב-equals:
Integer x = 200;
Integer y = 200;
System.out.println(x.equals(y));
פלט: true
הסיבה היא ש-equals משווה את הערך עצמו ולא את מיקום האובייקט בזיכרון.
עכשיו ננסה להשתמש ב-== :
Integer x = 200;
Integer y = 200;
System.out.println(x == y);
פלט: false
הסיבה היא שהאופרטור == משווה רפרנסים ולא ערכים.
אבל מה יקרה אם נשתמש בערך 100?
Integer x = 100;
Integer y = 100;
System.out.println(x == y);
פלט: true
רגע... למה הפעם קיבלנו true?
Java מכילה מנגנון אופטימיזציה בשם Integer Cache (או Integer Pool).
עבור ערכים בטווח:
-128 עד 127Java שומרת אובייקטים מוכנים מראש וממחזרת אותם במקום ליצור אובייקטים חדשים.
Integer x = 100;
Integer y = 100;
במקרה זה שני המשתנים מצביעים לאותו אובייקט בזיכרון ולכן:
x == yמחזיר true.
Integer x = 200;
Integer y = 200;
הערך 200 נמצא מחוץ לטווח ה-Cache ולכן נוצרים שני אובייקטים שונים.
כתוצאה מכך:
x == yמחזיר false.
בתקופה שבה זיכרון היה משאב יקר, המנגנון הזה סיפק שיפור משמעותי בביצועים ובצריכת הזיכרון.
כאשר Java ממירה אוטומטית מ-int ל-Integer:
Integer x = 100;
מאחורי הקלעים Java מבצעת פעולה דומה ל:
Integer x = Integer.valueOf(100);
המתודה valueOf בודקת האם הערך קיים ב-Cache ומחזירה אובייקט קיים במידת האפשר.
המנגנון ממומש בתוך המחלקה:
java.lang.Integerבעת טעינת המחלקה נוצר מערך Cache פנימי המכיל את הערכים בטווח הנתמך.
התשובה היא כן ולא.
באמצעות הפרמטר:
-XX:AutoBoxCacheMax=1000Java תשמור Cache עבור ערכים בטווח:
min:-128 max:1000כאשר משווים Integer-ים, מומלץ להשתמש ב-equals ולא ב-==.
Integer a = 100;
Integer b = 100;
System.out.println(a == b); // true
Integer c = 200;
Integer d = 200;
System.out.println(c == d); // false
System.out.println(c.equals(d)); // true
Integer Cache הוא אחד מאותם מנגנונים קטנים ב-Java שמזכירים לנו שלא תמיד מה שאנחנו רואים בקוד הוא כל הסיפור. לפעמים יש לא מעט קסם שמתרחש מאחורי הקלעים.