האם חתימת השיטה כוללת את סוג ההחזרה בג'אווה?

1. סקירה כללית

חתימת השיטה היא רק קבוצת משנה של כל הגדרת השיטה בג'אווה. לפיכך, האנטומיה המדויקת של החתימה עלולה לגרום לבלבול.

במדריך זה נלמד את המרכיבים של חתימת השיטה והשלכותיה על תכנות Java.

2. חתימת שיטה

שיטות ב- Java תומכות בעומס יתר, כלומר ניתן להגדיר שיטות מרובות עם אותו שם באותה מחלקה או אותה היררכיה של מחלקות. מכאן שעל המהדר להיות מסוגל לאגד סטטית את השיטה אליה מתייחס קוד הלקוח. מסיבה זו, השיטה חתימה מזהה באופן ייחודי כל שיטה.

על פי אורקל, השיטה החתימה מורכבת משמות וסוגי הפרמטרים. לכן, כל שאר המרכיבים של הצהרת השיטה, כגון שינויים, סוג החזרה, שמות פרמטרים, רשימת חריגים וגוף אינם חלק מהחתימה.

בואו נסתכל מקרוב על עומס יתר של השיטות ואיך זה קשור לחתימות שיטות.

3. העמסת שגיאות

בואו ניקח בחשבון את הקוד הבא:

הדפסת חלל ציבורית () {System.out.println ("החתימה היא: הדפס ()"); } הדפסת חלל ציבורית (פרמטר int) {System.out.println ("החתימה היא: print (int)"); }

כפי שאנו רואים, הקוד מתגבש שכן לשיטות יש רשימות של סוגי פרמטרים שונים. למעשה, המהדר יכול לאגד באופן קבוע כל קריאה זו או אחרת.

עכשיו בואו לבדוק אם זה חוקי להעמיס על ידי הוספת השיטה הבאה:

public int print () {System.out.println ("החתימה היא: print ()"); החזר 0; }

כאשר אנו מקדרים, אנו מקבלים שגיאה "השיטה מוגדרת כבר בכיתה". זה מוכיח את השיטה סוג החזרה אינו חלק מחתימת השיטה.

בואו ננסה את אותו הדבר עם משתנים:

הדפסת חלל סופית פרטית () {System.out.println ("החתימה היא: הדפס ()"); }

אנו עדיין רואים את אותה שגיאת "השיטה כבר מוגדרת בכיתה". לכן, השיטה חתימה אינה תלויה בשינויים.

ניתן לבדוק עומס יתר על ידי שינוי חריגים מושלכים על ידי הוספת:

הדפסת חלל ציבורית () זורקת את IllegalStateException {System.out.println ("החתימה היא: הדפס ()"); לזרוק IllegalStateException חדש (); }

שוב אנו רואים את השגיאה "השיטה כבר מוגדרת בכיתה", המציינת את הצהרת זריקה לא יכולה להיות חלק מהחתימה.

הדבר האחרון שאנו יכולים לבדוק הוא האם שינוי שמות הפרמטרים מאפשר העמסת יתר. בואו נוסיף את השיטה הבאה:

הדפסת חלל ציבורית (int anotherParameter) {System.out.println ("החתימה היא: print (int)"); }

כצפוי, אנו מקבלים את אותה שגיאת אוסף. זה אומר ש שמות פרמטרים אינם משפיעים על חתימת השיטה.

3. גנריות ומחיקת סוגים

עם פרמטרים גנריים, מחיקת סוג משנה את החתימה האפקטיבית. למעשה, זה עלול לגרום להתנגשות בשיטה אחרת המשתמשת בגבול העליון של הסוג הגנרי במקום באסימון הגנרי.

בואו ניקח בחשבון את הקוד הבא:

מחלקה ציבורית OverloadingErrors {public void printElement (T t) {System.out.println ("החתימה היא: printElement (T)"); } printElement בטל פומבי (Serializable o) {System.out.println ("החתימה היא: printElement (Serializable)"); }}

למרות שהחתימות נראות שונות, המהדר אינו יכול לאגד באופן סטטי את השיטה הנכונה לאחר מחיקת סוג.

אנו יכולים לראות את המהדר מחליף ט עם הגבול העליון, ניתן לסידור, עקב מחיקת סוגים. לפיכך, הוא מתנגש עם השיטה המשתמשת במפורש ניתן לבצע סדרתי.

היינו רואים את אותה תוצאה עם סוג הבסיס לְהִתְנַגֵד כאשר לסוג הגנרי אין כל קשר.

4. רשימות פרמטרים ופולימורפיזם

חתימת השיטה מביאה בחשבון את הסוגים המדויקים. זה אומר שאנחנו יכולים להעמיס שיטה שסוג הפרמטר שלה הוא תת-מחלקה או סופר-קלאס.

עם זאת, עלינו לשים לב במיוחד כ כריכה סטטית תנסה להתאים באמצעות פולימורפיזם, אגרוף אוטומטי וקידום סוג.

בואו נסתכל על הקוד הבא:

סכום מספר ציבורי (מונח שלם 1, מונח שלם 2) {System.out.println ("הוספת מספרים שלמים"); מונח החזר 1 + מונח 2; } סכום מספר ציבורי (מספר מונח 1, מספר מונח 2) {System.out.println ("הוספת מספרים"); term term1.doubleValue () + term2.doubleValue (); } סכום מספר ציבורי (Object object1, Object term2) {System.out.println ("הוספת אובייקטים"); החזר מונח1.hashCode () + term2.hashCode (); }

הקוד שלעיל חוקי לחלוטין ויורכב. בלבול עלול להיווצר בעת קריאה לשיטות אלה מכיוון שאיננו צריכים לדעת את חתימת השיטה המדויקת שאליה אנו קוראים, אלא גם כיצד Java נקשרת באופן סטטי בהתבסס על הערכים בפועל.

בואו נבדוק כמה שיחות שיטה שבסופו של דבר קשורות ל סכום (שלם, שלם):

StaticBinding obj = StaticBinding חדש (); obj.sum (Integer.valueOf (2), Integer.valueOf (3)); obj.sum (2, 3); obj.sum (2, 0x1);

לשיחה הראשונה יש לנו את סוגי הפרמטרים המדויקים שלם, שלם. בשיחה השנייה, Java תיבה אוטומטית int ל מספר שלם בשבילנו. לבסוף, ג'אווה תשנה את ערך הבייט 0x1 ל int באמצעות קידום סוג ואז תיבה אוטומטית אליו מספר שלם.

באופן דומה, יש לנו את השיחות הבאות שמתחברות ל סכום (מספר, מספר):

obj.sum (2.0d, 3.0d); obj.sum (Float.valueOf (2), Float.valueOf (3));

בשיחה הראשונה יש לנו לְהַכפִּיל ערכים שמתאגרפים אוטומטית אליהם לְהַכפִּיל. ואז, באמצעות פולימורפיזם, לְהַכפִּיל התאמות מספר. זהה, לָצוּף התאמות מספר לשיחה השנייה.

בואו נצפה בעובדה ששניהם לָצוּף ו לְהַכפִּיל לרשת מ מספר ו לְהִתְנַגֵד. עם זאת, מחייב ברירת המחדל הוא ל- מספר. זאת בשל העובדה שג'אווה תתאים אוטומטית לסוגי העל הקרובים ביותר התואמים לחתימת שיטה.

בואו ניקח בחשבון את קריאת השיטה הבאה:

obj.sum (2, "ג'ון");

בדוגמה זו יש לנו int ל מספר שלם תיבה אוטומטית לפרמטר הראשון. עם זאת, אין סכום (מספר שלם, מחרוזת) עומס יתר לשם שיטה זו. כתוצאה מכך, Java תעבור את כל סוגי הפרמטרים העל שיש להעביר מההורה הקרוב ביותר אליו לְהִתְנַגֵד עד שהוא ימצא התאמה. במקרה זה, זה נקשר ל סכום (אובייקט, אובייקט).

כדי לשנות את הכריכה המוגדרת כברירת מחדל, אנו יכולים להשתמש בהטלת פרמטרים מפורשת כדלהלן:

obj.sum ((Object) 2, (Object) 3); obj.sum ((מספר) 2, (מספר) 3);

5. פרמטרים של Vararg

עכשיו בואו נפנה את תשומת ליבנו לאיך varargs להשפיע על החתימה היעילה של השיטה וכריכה סטטית.

כאן יש לנו שיטה עמוסה בשימוש varargs:

סכום מספר ציבורי (אובייקט מונח 1, מונח אובייקט 2) {System.out.println ("הוספת אובייקטים"); החזר מונח1.hashCode () + term2.hashCode (); } סכום מספר ציבורי (Object object1, Object ... term2) {System.out.println ("הוספת ארגומנטים משתנים:" + term2.length); int result = term1.hashCode (); עבור (אובייקט o: מונח 2) {תוצאה + = o.hashCode (); } להחזיר תוצאה; }

אז מה החתימות היעילות של השיטות? את זה כבר ראינו סכום (אובייקט, אובייקט) היא החתימה לראשונה. טיעונים משתנים הם למעשה מערכים, ולכן החתימה האפקטיבית לשנייה לאחר ההידור היא סכום (אובייקט, אובייקט []).

שאלה מסובכת היא כיצד נוכל לבחור את השיטה המחייבת כשיש לנו רק שני פרמטרים?

בואו ניקח בחשבון את השיחות הבאות:

obj.sum (אובייקט חדש (), אובייקט חדש ()); obj.sum (אובייקט חדש (), אובייקט חדש (), אובייקט חדש ()); obj.sum (אובייקט חדש (), אובייקט חדש [] {אובייקט חדש ()});

ברור שהשיחה הראשונה תיקשר ל סכום (אובייקט, אובייקט) והשני ל סכום (אובייקט, אובייקט []). כדי לאלץ את ג'אווה לקרוא לשיטה השנייה עם שני אובייקטים, עלינו לעטוף אותה במערך כמו בשיחה השלישית.

הדבר האחרון שיש לציין כאן הוא שהכרזה על השיטה הבאה תתנגש עם גרסת vararg:

סכום מספר ציבורי (מונח אובייקט 1, אובייקט [] מונח 2) {// ...}

6. מסקנה

במדריך זה למדנו כי חתימות השיטה מורכבות מהשם ורשימת סוגי הפרמטרים. השינויים, סוג ההחזרה, שמות הפרמטרים ורשימת החריגים אינם יכולים להבדיל בין שיטות עומס יתר ולכן אינם חלק מהחתימה.

בדקנו גם כיצד מחיקת סוגים ומשתנים מסתירים את חתימת השיטה היעילה וכיצד אנו יכולים לעקוף את קשירת השיטה הסטטית של Java.

כרגיל, כל דגימות הקוד המוצגות במאמר זה זמינות ב- GitHub.