הפניות ומצביעים
הפניות ומצביעים: האמת על המשתנים שלכם
בניגוד למשתנים פרימיטיביים (כמו int או boolean) שמחזיקים את הערך עצמו, משתנים של מחלקות עובדים אחרת לגמרי. הם לא מכילים את האובייקט, אלא רק שלט רחוק שמצביע עליו. הבנת המנגנון הזה היא קריטית למניעת באגים מפתיעים.
האנלוגיה: השלט והטלוויזיה
תחשבו על המשתנה שלכם כעל שלט רחוק, ועל האובייקט כעל טלוויזיה.
- השלט (המשתנה) הוא קטן, יושב אצלכם ביד (ב"מחסנית"), ויש לו שם (כמו "השלט של הסלון").
- הטלוויזיה (האובייקט) היא גדולה, יושבת במקום אחר בחדר (ב"ערימה"), ואין לה באמת שם משלה.
- השלט לא מכיל את הטלוויזיה בתוכו. הוא רק יודע איפה היא נמצאת ויכול לשלוח לה פקודות (כמו "תחליפי ערוץ" או "תשני את השם שלך").
המשתנה (📱) מצביע על האובייקט (📺)
1 מבט אל תוך הזיכרון: מחסנית (Stack) וערימה (Heap)
המחסנית (Stack) - המשתנים
מכיל את הערך עצמו
מכיל רק כתובת!
הערימה (Heap) - האובייקטים
אובייקט מסוג Dog
- name: "Rex"
- age: 3
לאובייקט הזה אין שם!
שימו לב: המשתנה d1 יושב במחסנית ומכיל רק את הכתובת 0xAbC123. האובייקט האמיתי עם הנתונים ("Rex", 3) יושב בערימה בכתובת הזו.
2 התעלומה: שני שלטים על אותה טלוויזיה
מה קורה כשאנחנו עושים השמה בין שני משתני הפניה? כמו בשורה: Dog d2 = d1;
אנחנו לא משכפלים את האובייקט (את הטלוויזיה). אנחנו פשוט קונים עוד שלט אוניברסלי (d2) ומכנתים אותו לאותו תדר של השלט הראשון. עכשיו יש לנו שני שלטים ששולטים על אותה טלוויזיה בדיוק.
שני המשתנים מכילים את אותה כתובת!
אובייקט מסוג Dog
- name: "Rex Lassie"
- age: 3
שינוי דרך d2 משפיע על מה ש-d1 רואה!
Dog d1 = new Dog("Rex");
Dog d2 = d1; // העתקת הכתובת בלבד!
// שינוי האובייקט דרך השלט השני
d2.name = "Lassie";
// הדפסה דרך השלט הראשון
System.out.println(d1.name);
חוקי הברזל של הפניות
- המשתנה הוא לא האובייקט: המשתנה הוא רק קופסה קטנה במחסנית שמחזיקה כתובת. האובייקט הוא הישות הגדולה בערימה.
- לאובייקט אין שם: הדרך היחידה להגיע לאובייקט היא דרך משתנה שמחזיק את הכתובת שלו. אם נאבד את כל המשתנים שמצביעים על אובייקט, הוא ילך לאיבוד בזיכרון (ו"אוסף הזבל" ינקה אותו).
- השמה מעתיקה כתובות: הפקודה
d2 = d1לא יוצרת כלב חדש. היא רק גורמת ל-d2להצביע לאותו כלב ש-d1מצביע עליו. - שינוי משותף: אם שני משתנים מצביעים לאותו אובייקט, כל שינוי שנעשה דרך אחד מהם ישתקף מיידית כשנסתכל דרך השני, כי הם מסתכלים על אותו הדבר בדיוק.