מדוע מחרוזת אינה ניתנת לשינוי בג'אווה?

1. הקדמה

בג'אווה, מיתרים הם בלתי ניתנים לשינוי. שאלה ברורה שנפוצה למדי בראיונות היא "מדוע מיתרים מעוצבים כבלתי ניתנים לשינוי בג'אווה?"

ג'יימס גוסלינג, יוצר ג'אווה, נשאל פעם בראיון מתי צריך להשתמש בבלתי משתנה, עליו הוא עונה:

הייתי משתמש בבלתי משתנה מתי שאני יכול.

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

במדריך זה נחקור עוד מדוע מעצבי שפת Java החליטו להמשיך חוּט בלתי ניתן לשינוי.

2. מהו אובייקט בלתי ניתן לשינוי?

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

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

3. למה כן חוּט בלתי ניתנים לשינוי בג'אווה?

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

בואו נדון איך הדברים האלה עובדים.

3.1. להציג בפני חוּט בריכה

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

בריכת המיתרים של Java היא אזור הזיכרון המיוחד שבו מיתרים מאוחסנים על ידי JVM. מאז מיתרים הם בלתי ניתנים לשינוי ב- Java, ה- JVM מייעל את כמות הזיכרון שהוקצה להם על ידי אחסון עותק אחד בלבד של כל מילולית חוּט בבריכה. תהליך זה נקרא התמחות:

מחרוזת s1 = "שלום עולם"; מחרוזת s2 = "שלום עולם"; assertThat (s1 == s2) .isTrue ();

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

יש לנו מאמר נפרד המוקדש ל- Java חוּט בריכה. למידע נוסף, עבור למאמר זה.

3.2. בִּטָחוֹן

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

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

בטל criticalMethod (שם משתמש מחרוזת) {// לבצע בדיקות אבטחה אם (! isAlphaNumeric (userName)) {זרוק אבטחה חדשה של אבטחה (); } // בצע כמה משימות משניות אתחול DataBase (); // חיבור משימות קריטי. executeUpdate ("עדכן לקוחות סטטוס = 'פעיל'" + "WHERE UserName = '" + שם משתמש + "'"); }

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

זכור כי לשיטת המתקשר הלא אמין שלנו עדיין יש התייחסות לכך שם משתמש לְהִתְנַגֵד.

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

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

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

3.3. סִנכְּרוּן

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

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

3.4. מטמון Hashcode

מאז חוּט אובייקטים משמשים בשפע כמבנה נתונים, הם נמצאים בשימוש נרחב גם ביישומי חשיש כמו מפת גיבוב, טבלת גיבוב, HashSetוכו 'בעת פעולה על יישומי חשיש אלה, hashCode () שיטה נקראת לעתים קרובות למדי עבור דלי.

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

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

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

3.5. ביצועים

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

מאז חוּט הוא מבנה הנתונים הנפוץ ביותר, המשפר את הביצועים של חוּט יש השפעה ניכרת על שיפור ביצועי היישום כולו באופן כללי.

4. מסקנה

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

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