עבור לתוכן
View in the app

A better way to browse. Learn more.

HWzone

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Java- איך נמנעים מ-alasing בבנאים ?

Featured Replies

פורסם

אני לומד קורס ג'אווה בפתוחה ובתרגילים תמיד מזהירים אותנו מ-alasing

איך אני יודע איפה לזהות אותם בבנאים (שם הנק' הקריטיות נמצאות ?) ?

פורסם

בכל מקום שאתה מחזיר או מאתחל אובייקט עשה לך נוהג ותמיד תחזיר \ תאתחל באמצעות new ובנאי כלשהו של המחלקה שאליה האוביקט שייך.

פורסם
  • מחבר

למשל משהו כזה:


public class test
{
public string _str;


public test(string str)
{
_str = str;
}
}

פורסם
  • מחבר

אין בעיה אני פשוט רוצה לדעת איך אני נזהר ה-alasing ואיפה לשים לב לא לעשות \ נק' בעיתיות כו'

פורסם

יכול להיות שהתכוונת ל aliasing?

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

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



public class Test
{
public string _str;


public Test(List<String> l)
{
_str = l.get(0);
}
}

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

וד"א, תתרגל להשתמש תמיד בקונבנציית השמות, אפילו בדוגמאות טריוויאליות (שם המחלקה צריך להתחיל באות גדולה)

פורסם

א. גם בקוד הזה אין שום בעיה (למעשה הוא כמעט זהה לקוד ש-gal_i50 פרסם).

ב. בג'אווה רק פרימיטיביים עוברים by value, כל השאר עובר by reference.

פורסם

שניצל

א. כן זה נכון שבקוד אין בעיה, אולם זה בגלל שהרשימה מכילה מחרוזות ואלו מוגדרות immutable ע"' הקומפיילר, כלומר בהרבה מקרים המחרוזות כלל לא ישבו בheap. אם למשל הרשימה היתה מחזיקה Date אזי היתה לנו בעיה -



public class Test
{
public Date _date;


public Test(List<Date> l)
{
_date = l.get(0);
}

public static void main(String[] args)
{
List<Date> l = new ArrayList<Date>();
l.add(new Date(10000));
Test t = new Test(l);
System.out.println(t._date == l.get(0));
System.out.println(l.get(0));
System.out.println(t._date);
l.get(0).setDate(2000);
System.out.println(t._date == l.get(0));
System.out.println(l.get(0));
System.out.println(t._date);
}
}


output

true
Thu Jan 01 02:00:10 IST 1970
Thu Jan 01 02:00:10 IST 1970
true
Mon Jun 23 02:00:10 IDT 1975
Mon Jun 23 02:00:10 IDT 1975


הנה הצלחתי לשנות את הערך של משתנה המחלקה _date מבלי להתייחס אליו ישירות (דרך שינוי האיבר ברשימה)

וזו בדיוק הדגמה של aliasing

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

הסבר מלא אפשר למצוא במאמר הזה

http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html

פורסם

א. נכון, אבל מה ההבדל כאן בין להעביר רשימה לבין להעביר אובייקט בודד מסוג Date?

ב. צודק, התכוונתי שהאובייקטים עצמם עוברים by reference, והמצביעים להם עוברים by value.

פורסם

נכון, אפקט aliasing מתקיים גם באובייקט בודד של Date

למען פותח השירשור אסכם את הנושא כך:

aliasing פירושו השמה של שניים או יותר מצביעים לאותו אובייקט

מכאן משתמע שאין כלל אפשרות לaliasing במשתנים פרימיטיביים ואוסיף שגם במחרוזות מעצם טבען המיוחד בג'אווה (immutable)

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

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

ולמען המפתחים המתקדמים בינינו אוסיף שזו אחת מהטעויות שאינה מתקיימת בשפות תכנות פונקציונאליות (functional programming) מכיוון שקיימת שם דרישת סף שכל פונקציה (=מתודה) לא תשנה שום משתנים שאינם לוקאליים.

ארכיון

דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.

דיונים חדשים

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.