ג'אווה מאפשרת להגדיר במחלקה מספר שירותים עם אותו שם, בתנאי
שהטיפוס ו/או המספר של הארגומנטים שונה. למשל, אפשר להגדיר שירות בשם m
שמקבל int
כארגומנט וגם שירות m שמקבל double
.
בעיני השפה והקומפיילר, אלה שני שירותים שונים שאין ביניהם שום קשר.
הקומפיילר נותן לכל אחד מהם שם ייחודי (אבל אינו מגלה לנו מהו אותו שם
ייחודי). נניח לצורך הדיון שהשמות הנסתרים שבהם הקומפיילר מתייחס לשירותים
הללו הם m_int
ו-m_double
.
כאשר קוראים לשירות ששמו m, הקומפיילר בודק מהו הטיפוס של הארגומנט. אם
העברנו int, הקומפיילר למעשה משנה את הקריאה לקריאה לשירות ששמו הנסתר m_int
,
ואם העברנו double
הוא משנה את הקריאה לקריאה ל-m_double
.
אם קראנו לשירות והעברנו ארגומנט שאינו int ואינו double
,
הקומפיילר בודק האם אפשר להמיר באופן בטוח את הארגומנט. אם אפשר להמיר
אותו ל-int
או ל-double
,
הקומפייר מבצע את ההמרה וקורא לגרסה המתאימה של השירות המועמס. בהמשך נראה
שיש מקרים שבהם יש כמה המרות בטוחות שכל אחת מהן תגרור קריאה לגרסה אחרת
של שירות מועמס; במקרה כזה הקריאה לשירות לא חוקית.
אי אפשר להגדיר מספר שירותים עם אותו שם ואותם טיפוסי ארגומנטים שנבדלים רק בטיפוס המוחזר. זה לא חוקי בג'אווה.
ככלל, אנו ממליצים להימנע מהעמסה. העמסה גורמת לתוכניות להיראות
אלגנטיות (כי שמות השירותים קצרים), אבל היא גם גורמת לכמה בעיות. בעיה
אחת היא שלא תמיד ברור מהקוד לאיזה מהגרסאות המועמסות קוראים. האם
הקומפיילר יפרש את הקריאה ל-m כקריאה ל-m(int)
או לקריאה ל-m(double)
? במקרים מסובכים לא תמיד
קל לדעת. כדי להבין את הבעיות האחרות, כדאי לפתור את השאלות.
מה קורה כאשר קוראים לשירות printWithType
בתוכנית המצורפת עם ארגומנט מטיפוס short
, long
, float
, char
, byte
, או boolean
? עני ואחר כך נסי.overTheTop
עם שני ארגומנטים מטיפוס int
? עני ורק אחר כך נסי.overTheTop
היתה מוגדרת, ובמחלקה אחרת היינו קוראים לשירות עם שני ארגומנטים מטיפוס int
. ברור שזה תקין, מכיון שאין כאן שום העמסה ומכיון שההמרה של int
ל-double
היא בטוחה. כעת אנו מוסיפים את הגרסה השניה של overTheTop
. מה קורה? המפתח לתשובה טמון בהסבר שלמעלה לגבי התנהגות הקומפיילר. זו דוגמה לבעיה שנקראת שבריריות (fragility), והיא אחת הסיבות העיקריות להמלצה שלא להעמיס.