שאלת מבחן בתכנות מונחה עצמים - אוניברסיטת בר-אילן 2023 - מעקב אחר קוד
בג'אווה, מה מבין הבאים לא יכולה להיות תוצאת הרצת המתודה
תזכורת:
.1 לא ייתכן שהמתודה תחזיר
.2 לא ייתכן שהמתודה תחזיר
.3 לא ייתכן שייזרק חריג מסוג
.4 לא ייתכן שהמתודה תחזיר
isWonderful?תזכורת:
equals היא מתודה המוגדרת במחלקה Object ואשר מחזירה true רק אם עצם הקלט שווה בתוכנו לעצם שקרא למתודה. ניתן להניח כי כל המחלקות מממשות את equals כנדרש..1 לא ייתכן שהמתודה תחזיר
wonder.2 לא ייתכן שהמתודה תחזיר
won.3 לא ייתכן שייזרק חריג מסוג
NullPointerException.4 לא ייתכן שהמתודה תחזיר
wonfulהעתק שאלה
שתף שאלה
סמן כחשוב
סמן כבוצע
אוניברסיטת בר-אילןמועד א · 2023 · סמסטר ב
★★★★★
מעקב אחר קודאובייקטיםחריגות
נתחו את מצב המצביעים
o1 ו-o2 רגע לפני ביצוע התנאי השני (!o1.equals(o2)). שימו לב כיצד התנאי והפקודות בבלוק ה-if הראשון משפיעים על מצבם.התשובה הנכונה היא 4. לא ייתכן שהמתודה תחזיר
ננתח את זרימת המתודה
1. המשתנה
2. התנאי הראשון,
3. התנאי השני,
כעת נבחן את כלל המקרים האפשריים (בהנחה שלא נזרק חריג):
מקרה א': `o1` ו-`o2` מצביעים לאותו אובייקט (`o1 == o2`).
מקרה ב': `o1` ו-`o2` מצביעים לאובייקטים שונים (`o1 != o2`).
בשני המקרים, התנאי השני
מכאן נובע שהמחרוזת
בדיקת שאר האפשרויות:
wonful.ננתח את זרימת המתודה
isWonderful:1. המשתנה
s מאותחל למחרוזת "won".2. התנאי הראשון,
if (o1 != o2), בודק שוויון מצביעים (reference equality). כלומר, האם o1 ו-o2 מצביעים לאותו אובייקט בזיכרון.3. התנאי השני,
if (!o1.equals(o2)), בודק שוויון תוכני (content equality). כלומר, האם האובייקטים שקולים בתוכנם, על פי המימוש של המתודה equals.כעת נבחן את כלל המקרים האפשריים (בהנחה שלא נזרק חריג):
מקרה א': `o1` ו-`o2` מצביעים לאותו אובייקט (`o1 == o2`).
- התנאי הראשון
(o1 != o2)יתקיים כ-false. - גוף ה-
ifהראשון לא יתבצע, והמשתנהsיישאר"won". - נגיע לתנאי השני
(!o1.equals(o2)). מכיוון ש-o1ו-o2הם אותו מצביע, ובהתאם לחוזה שלequals, הביטויo1.equals(o2)חייב להחזירtrue. - לכן, התנאי
!o1.equals(o2)יתקיים כ-false. - גוף ה-
ifהשני לא יתבצע. - המתודה תחזיר
"won".
מקרה ב': `o1` ו-`o2` מצביעים לאובייקטים שונים (`o1 != o2`).
- התנאי הראשון
(o1 != o2)יתקיים כ-true. - גוף ה-
ifהראשון יתבצע: - המצביע
o1יקבל את ערך המצביעo2באמצעות הפקודהo1 = o2. כעת, `o1` ו-`o2` מצביעים לאותו אובייקט. - למשתנה
sתתווסף המחרוזת"der", וערכו יהיה"wonder". - נגיע לתנאי השני
(!o1.equals(o2)). מכיוון שכעתo1ו-o2הם אותו מצביע, הביטויo1.equals(o2)חייב להחזירtrue. - לכן, התנאי
!o1.equals(o2)יתקיים כ-false. - גוף ה-
ifהשני לא יתבצע. - המתודה תחזיר
"wonder".
בשני המקרים, התנאי השני
(!o1.equals(o2)) תמיד מתקיים כ-false. הסיבה לכך היא שבזמן הערכת התנאי, המשתנים o1 ו-o2 תמיד יחזיקו את אותו המצביע. לכן, גוף ה-if השני, s += "ful";, הוא למעשה קוד בלתי נגיש (unreachable code).מכאן נובע שהמחרוזת
"ful" לעולם לא תתווסף ל-s, וכל פלט המכיל אותה אינו אפשרי. לכן, לא ייתכן שהמתודה תחזיר "wonful".בדיקת שאר האפשרויות:
wonder: אפשרי, למשלisWonderful(new String("a"), new String("b")).won: אפשרי, למשלObject obj = new Object(); isWonderful(obj, obj).NullPointerException: אפשרי. למשל, אםo2הואnullו-o1אינוnull, אז בתוך ה-ifהראשוןo1יהפוך ל-null, והקריאהo1.equals(o2)תזרוק חריג. גם אם שניהםnullמההתחלה, הקריאה ל-equalsתזרוק חריג.