ההבדלים בין Final, Final ו- Finalize ב- Java

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

במדריך זה נסקור סקירה של שלוש מילות מפתח של Java: סופית, סוף סוף ו לְסַכֵּם.

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

2. סופי מילת מפתח

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

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

  • הכנת שיעור סופי פירושו שלא ניתן יהיה להרחיב את המעמד
  • מוֹסִיף סופי לשיטה פירושו שלא ניתן יהיה לבטל את השיטה הזו
  • לבסוף, לשים סופי מול שדה, משתנה או פרמטר פירושו שברגע שהוקצה ההפניה אז לא ניתן לשנות אותה (אולם אם הכוונה היא לאובייקט משתנה, המצב הפנימי שלו יכול להשתנות למרות שהוא סופי)

מאמר מפורט אודות סופי מילת מפתח תוכל למצוא כאן.

בוא נראה איך ה סופי מילת המפתח עובדת באמצעות כמה דוגמאות.

2.1. סופי שדות, פרמטרים ומשתנים

בואו ניצור הוֹרֶה כיתה עם שניים int שדות, א סופי אחד, ולא קבוע אחרון:

כיתה ציבורית הורה {int שדה 1 = 1; שדה int סופי 2 = 2; הורה () {field1 = 2; // שדה OK 2 = 3; // שגיאת אוסף}}

כפי שאנו רואים, המהדר אוסר עלינו להקצות ערך חדש ל- שדה 2.

בואו כעת נוסיף שיטה עם טיעון קבוע וסופי:

 שיטת בטל 1 (int arg1, int arg2 final) {arg1 = 2; // OK arg2 = 3; // שגיאת אוסף}

בדומה לשדות, לא ניתן להקצות משהו arg2 כפי שהוא הוכרז כסופי.

כעת ניתן להוסיף שיטה שנייה כדי להמחיש כיצד זה עובד עם משתנים מקומיים:

 בטל שיטה 2 () {final int localVar = 2; // אישור localVar = 3; // שגיאת אוסף}

שום דבר לא מפתיע קורה, המהדר לא נותן לנו להקצות ערך חדש localVar לאחר משימתה הראשונה.

2.2. סופי שיטה

עכשיו נניח שאנחנו מכינים שיטה 2 סופי וליצור תת-מחלקה של הוֹרֶה, נניח יֶלֶד, בו אנו מנסים לעקוף את שתי שיטות הסופר-קלאס שלה:

מחלקה ציבורית ילד מאריך את ההורה {@ שיטה בטלנית בטל חלל 1 (int arg1, int arg2) {// OK} @ שיטת בטל סופית בטל 2 () {// שגיאת קומפילציה}}

כפי שאנו רואים, אין שום בעיה לעקוף method1 (), אך אנו מקבלים שגיאת אוסף כאשר אנו מנסים לעקוף method2 ().

2.3. סופי מעמד

ולסיום, בואו נעשה את יֶלֶד גמר הכיתה ולנסות ליצור תת-מחלקה שלו, נֶכֶד:

כיתת גמר ציבורית ילד מאריך את ההורה {// ...}
הכיתה הציבורית GrandChild מרחיבה את הילד {// שגיאת אוסף}

שוב, המתלונן מתלונן. ה יֶלֶד השיעור הוא סופי ולכן אי אפשר להרחיב אותו.

3. סוף כל סוף לַחסוֹם

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

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

יש לנו מאמר מעמיק על טיפול בחריגים ב- Java כאן.

עכשיו בואו נדגים א סוף כל סוף חסום בדוגמה קצרה. ניצור דמה רָאשִׁי() שיטה עם נסה / לתפוס / סוף סוף מִבְנֶה:

main static public void (String args []) {try {System.out.println ("הפעל חסימת נסיון"); לזרוק חריג חדש (); } לתפוס (חריג e) {System.out.println ("ביצוע בלוק תפוס"); } סוף סוף {System.out.println ("הפעל סוף סוף חסום"); }}

אם נפעיל קוד זה, הוא יפיק את הדברים הבאים:

ביצוע חסימת ניסיון ביצוע חסימת תפוס ביצוע חסימה לבסוף

בואו ונשנה את השיטה על ידי הסרת גוש התפס (והוסף זורק חריג לחתימה):

main static public ריק (String args []) זורק Exception {try {System.out.println ("Execute try block"); לזרוק חריג חדש (); } סוף סוף {System.out.println ("הפעל סוף סוף חסום"); }}

התפוקה היא כעת:

בצע חסימה נסה בצע חסימה לבסוף

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

4. לְסַכֵּם שיטה

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

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

שוב, מאמר מפורט המכסה את לְסַכֵּם שיטה ניתן למצוא כאן.

בואו נראה דוגמה לאיך זה עובד. נשתמש System.gc () להציע את JVM להפעיל איסוף זבל:

 @Override הריק מוגן finalize () זורק Throwable {System.out.println ("בצע את שיטת הסיום"); סופי. סיים (); }
 סטטי ציבורי ריק ריק (String [] args) זורק Exception {FinalizeObject object = new FinalizeObject (); אובייקט = null; System.gc (); Thread.sleep (1000); }

בדוגמה זו אנו עוקפים לְסַכֵּם() שיטה באובייקט שלנו וליצור a רָאשִׁי() שיטה אשר מיידית את האובייקט שלנו ומפילה מיד את ההפניה על ידי הגדרת המשתנה שנוצר ל- ריק.

אחרי זה אנחנו מתקשרים System.gc () להפעיל את אוסף זבל (לפחות אנו מצפים שהיא תפעל) ומחכה לשנייה (רק כדי להבטיח שה- JVM לא נסגר לפני כן אוסף זבל יש את ההזדמנות להתקשר לְסַכֵּם() שיטה).

הפלט של ביצוע קוד זה צריך להיות:

בצע את שיטת הסיום

שים לב שזה נחשב לנהוג רע לבטל לְסַכֵּם() שיטה כפי הביצוע שלה תלוי איסוף זבל אשר ביד ה JVM. בנוסף, שיטה זו הייתה הוצא משימוש מאז Java 9.

5. מסקנה

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

את הקוד המלא של המאמר ניתן למצוא באתר GitHub.