JavaRush /בלוג Java /Random-HE /הפסקת קפה מס' 121. מהו Classpath ב-Java וכיצד להתקין אותו...

הפסקת קפה מס' 121. מהו Classpath ב-Java וכיצד להתקין אותו? חוסר שינוי בג'אווה

פורסם בקבוצה

מהו Classpath ב-Java וכיצד להתקין אותו?

מקור: בינוני הכרת יסודות התכנות וזרימת הביצוע של קבצי תוכניות עוזרת לנו להבין שפה. הכרת הפרמטר Classpath הוא אחד המושגים הבסיסיים שכל מפתח Java צריך לדעת. היום נדון מהו נתיב מחלקה ( Classpath ), כיצד להגדיר אותו וכיצד הוא עוזר ל-JVM לבצע קבצי מחלקה. הפסקת קפה מס' 121.  מהו Classpath ב-Java וכיצד להתקין אותו?  חוסר שינוי בג'אווה - 1

מה זה Classpath?

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

כיצד Classpath מסייע ל-JVM בביצוע קבצי מחלקה

נתחיל עם דוגמה. נניח שיש לנו קובץ Main.java שנמצא בתיקייה /Users/vikram/Documents/test-java/src/com/programming/v1/Main.java .
package com.programming.v1;

public class Main {
    public static void main(String[] args) {
        System.out.println("Hello classpath");
    }
}
נניח שאנחנו ב- /Users/vikram/Documents ורוצים להרכיב את המחלקה הזו:
javac test-java/src/com/programming/v1/Main.java
כעת, כדי להפעיל קובץ מחלקה זה, עלינו לומר ל-Java Virtual Machine היכן לחפש את קובץ ה-.class באמצעות classpath או דגל cp בפקודה java .
vg@lp1 Documents % java -cp "test-java/src" com.programming.v1.Main
Hello classpath
vg@lp1 Documents % java -classpath "test-java/src" com.programming.v1.Main
Hello classpath
הפרמטר הראשון הוא תיקיית השורש שבה כתובה החבילה. הפרמטר השני הוא שם החבילה עם שם המחלקה. כאשר מופעלת פקודת Java, ה-Java Virtual Machine מסתכל בתיקיית test-java/src ולאחר מכן טוען את המחלקה הראשית כדי לבצע אותה.

כיצד להגדיר משתנה Classpath

ניתן להגדיר את המשתנה Classpath כפי שמוצג להלן במכונות לינוקס:
export CLASSPATH="test-java/src"
ניתן להוסיף/לעדכן Classpath במחשב Windows באמצעות משתני סביבה. לאחר הגדרת משתנה הסביבה, ניתן לבצע את פקודת java כפי שמוצג להלן:
vg@lp1 Documents % java com.programming.v1.Main
Hello classpath
זה כל מה שיש לדעת על Classpath . תודה שקראת!

חוסר שינוי בג'אווה

מקור: משתנים בינוניים ב-Java הם משני סוגים: פרימיטיבי והתייחסות. הכל ב-Java מועבר לפי ערך, אבל במקרה של סוגי הפניות, ניתן לעדכן את נתוני המקור באמצעות כתובת הזיכרון שעברה. הפסקת קפה מס' 121.  מהו Classpath ב-Java וכיצד להתקין אותו?  חוסר שינוי בג'אווה - 2מילת המפתח הסופית משמשת כדי לגרום למשתנה לפעול כקבוע, כלומר להימנע מהקצאה מחדש. זה עובד היטב עבור פרימיטיביים שאין להם זיכרון ערימה, ואילו עבור סוגי התייחסות רק ההקצאה מחדש מוגבלת וניתן לשנות את המצב הפנימי. זה יכול להוביל לבעיות במקביל ולתנאי מרוץ רבים. לפיכך, הכללת מאפיינים בלתי ניתנים לשינוי בסוג רגיל בג'אווה מספקת יתרונות רבים.

היתרונות של אי-שינוי בג'אווה

1. בטיחות חוטים

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

2. סוג בסיסי

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

מאפיינים

1. שדות פרטיים וסופיים

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

2. אין שיטות שינוי

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

3. שיעור גמר

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

4. עותקים הגנתיים

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

יישום

עוֹבֵד

import java.time.LocalDate;
import java.util.List;

import static java.util.List.copyOf;

public final class Employee {

    private final long id;
    private final String name;
    private final LocalDate joinDate;
    private final List<String> achievements;

    public Employee(long id,
                    String name,
                    LocalDate joinDate,
                    List<String> achievements) {
        this.id = id;
        this.name = name;
        this.joinDate = joinDate;
        this.achievements = copyOf(achievements);
    }

    public long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public LocalDate getJoinDate() {
        return joinDate;
    }

    public List<String> getAchievements() {
        return achievements;
    }
}
  • לא לכל השדות יש עותקים מגנים בבנאי. הסיבה לכך היא ש- id הוא פרימיטיבי ושדות השם וה- joinDate הם סוגים בלתי ניתנים לשינוי. לא ניתן לשנות אותם על ידי המתקשר והם יישארו ללא שינוי, בעוד ששדה ההישגים דורש עותק של הארגומנט שנעשה בשיטת List.copyOf . הסיבה לכך היא copyOf מחזירה רשימה בלתי ניתנת לשינוי .

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

שיפורים

לפני Java 16

ניתן לשפר את יישום העובד עם ספריות כגון Lombok . זה מפחית את מידת המלל בקוד ועוזר לו להיראות נקי יותר. הספרייה מגיעה עם הערות לקיצור הקוד הסטנדרטי. ניתן להשתמש ב-@Value (ביאור) ליצירת קבלנים ובנאי עבור כל הארגומנטים. זה יוצר גם שיעור סופי ושדות פרטיים ואחרונים . כהערה, הוא גם מייצר שיטות toString , equals ו- hashCode . ניתן לשכתב את יישום העובד באמצעות @Value כפי שמוצג להלן:
import lombok.Value;

import java.time.LocalDate;
import java.util.List;

import static java.util.List.copyOf;

@Value
public class Employee {

    long id;
    String name;
    LocalDate joinDate;
    List<String> achievements;

    public Employee(long id,
                    String name,
                    LocalDate joinDate,
                    List<String> achievements) {
        this.id = id;
        this.name = name;
        this.joinDate = joinDate;
        this.achievements = copyOf(achievements);
    }
}

Java 16 ואילך

מהדורת Java 16 הציגה פונקציית Record חדשה . אלה (כפי שנאמר על ידי JEP) הם מחלקות הפועלות כנשאים שקופים של נתונים בלתי ניתנים לשינוי וניתן לחשוב עליהם כעל טופלים נומינליים. ניתן להטמיע מחדש את מחלקת העובד כעובד רשומה כפי שמוצג להלן.
import java.time.LocalDate;
import java.util.List;

import static java.util.List.copyOf;

public record Employee(long id,
                       String name,
                       LocalDate joinDate,
                       List<String> achievements) {

    public Employee(long id,
                    String name,
                    LocalDate joinDate,
                    List<String> achievements) {
        this.id = id;
        this.name = name;
        this.joinDate = joinDate;
        this.achievements = copyOf(achievements);
    }
}

פגמים

הבעיה היחידה עם אי-שינוי היא תוספת הזיכרון והעיבוד שאפילו שינוי קטן דורש. בכל פעם אתה צריך ליצור אובייקט חדש, שיכול להיות יקר מאוד. כדי לעקוף את החיסרון הזה, אתה יכול ליישם מנגנונים כמו שמירה במטמון ושמירת תוצאות.
הערות
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION