Menu

איך מריצים Java: קומפילציה עם javac והרצה עם java

מחזור שני השלבים, קומפילציה ואז הרצה, שעומד מאחורי כל תוכנית Java: הופכים קוד מקור .java ל-bytecode עם javac, ואז מריצים את קובץ ה-.class עם java.

בדף הזה יש עורכים שאפשר להריץ - לערוך, להריץ ולראות את הפלט מיד.

קומפילציה, ואז הרצה

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

שני השלבים האלה מתאימים לשני כלי שורת פקודה שמגיעים עם ה-JDK:

  • javac: המהדר. הוא קורא את Main.java וכותב את Main.class (bytecode).
  • java: המפעיל. הוא מפעיל את ה-JVM ומריץ את ה-bytecode שב-Main.class.

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

שתי הפקודות על המחשב שלכם

נניח שהקוד הזה שמור אצלכם בתור Main.java:

public class Main {
    public static void main(String[] args) {
        System.out.println("Hello from the terminal");
    }
}

פתחו טרמינל בתיקייה שמכילה את הקובץ והריצו את המהדר:

javac Main.java

אם הקוד עובר קומפילציה נקייה, javac לא מדפיס כלום ויוצר קובץ חדש, Main.class, ליד קוד המקור. קובץ ה-.class הזה הוא ה-bytecode: הוא לא טקסט קריא, והוא לא קשור למערכת ההפעלה שלכם.

עכשיו הפעילו אותו עם הפקודה java:

java Main
Hello from the terminal

כאן נמצאת הטעות הנפוצה ביותר של מתחילים: כדי להפעיל את התוכנית מריצים java, לא javac, ומעבירים את שם המחלקה בלי סיומת. זה java Main, אף פעם לא java Main.class ואף פעם לא java Main.java.

שם הקובץ חייב להתאים למחלקה הציבורית

Java אוכפת כלל שמפתיע חדשים: מחלקה public חייבת להיות בקובץ עם בדיוק אותו שם, ועוד .java. public class Main חייבת להיות ב-Main.java. טעות באותיות גדולות וקטנות, ו-javac מסרב לקמפל.

// This is in a file called Greeting.java
public class Greeting {   // ERROR: class Greeting should be in Greeting.java... wait, it is
    public static void main(String[] args) {
        System.out.println("Hi");
    }
}

אי ההתאמה שבאמת מכשילה אנשים עדינה יותר: לקרוא לקובץ greeting.java (באותיות קטנות) כשהמחלקה היא Greeting, או לשמור Main.java ולכתוב public class Hello. המהדר מדווח משהו כמו:

Main.java:1: error: class Hello is public, should be declared in a file named Hello.java

התיקון תמיד זהה: הפכו את שם הקובץ ואת שם המחלקה הציבורית לזהים, תו אחר תו.

הקיצור: הרצת קובץ יחיד ישירות

מאז JDK 11 אפשר לדלג על שלב הקומפילציה המפורש עבור קובץ מקור יחיד. הפקודה java תקמפל אותו בזיכרון ותריץ אותו בבת אחת, בלי לכתוב קובץ .class לדיסק:

java Main.java

זה מושלם לניסויים מהירים ולסקריפטים קטנים. שימו לב להבדל במה שמעבירים:

  • java Main: מריץ Main.class שכבר עבר קומפילציה.
  • java Main.java: מקמפל ומריץ את קובץ המקור בבת אחת.

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

העברת ארגומנטים לתוכנית

זוכרים את String[] args ב-main? אלה ארגומנטים של שורת הפקודה. כל מה שמקלידים אחרי שם המחלקה בפקודה java נוחת במערך הזה:

על המחשב שלכם הייתם מעבירים לו ארגומנטים כך:

java Main hello world
First argument: hello
Total arguments: 2

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

קריאת הודעות השגיאה של המהדר

כש-javac דוחה את הקוד, הוא אומר לכם את הקובץ, את השורה ומה השתבש. ללמוד לקרוא את ההודעות האלה זה חצי מהדרך לצאת מתקיעה. הנה קלאסיקה, נקודה-פסיק חסרה:

public class Main {
    public static void main(String[] args) {
        System.out.println("Oops")   // no semicolon
    }
}
Main.java:3: error: ';' expected
        System.out.println("Oops")
                                  ^
1 error

הסימן (^) מצביע על המקום שבו המהדר ציפה למשהו. Main.java:3 הוא הקובץ ומספר השורה. אל תנחשו: קראו את השורה, תקנו את הדבר האחד שהיא מציינת וקמפלו שוב. שגיאות קומפילציה אומרות ששום דבר עוד לא רץ; שגיאות זמן ריצה (שנראות אחרת) אומרות שהתוכנית התחילה ואז נכשלה.

תוכנית לבדיקת שפיות

הריצו אותה בעורך, או שמרו אותה כ-Main.java והריצו javac Main.java ואז java Main על המחשב שלכם. אם אתם רואים את שלוש השורות, שרשרת הכלים שלכם עובדת מקצה לקצה:

שלושה דברים מופיעים כאן שתכירו כמו שצריך בקרוב: משתנה מסוג int, שרשור מחרוזות עם +, ומערך עם ה-.length שלו. בינתיים מספיק שהתוכנית עוברת קומפילציה ומדפיסה.

הבא: התחביר של Java

הרצתם כמה תוכניות, אבל עד עכשיו דילגנו על סימני הפיסוק: הסוגריים המסולסלים, הנקודה-פסיק, public static void main, ולמה כל שורה נראית כמו שהיא נראית. העמוד הבא מפרק את התחביר של Java חלק אחר חלק, כדי שהמבנה יפסיק להרגיש כמו קוד טקס ויתחיל להיות הגיוני.

שאלות נפוצות

איך מריצים תוכנית Java?

שומרים את הקוד בקובץ שנקרא על שם המחלקה הציבורית (למשל Main.java), פותחים טרמינל בתיקייה הזו ומריצים שתי פקודות: javac Main.java כדי לקמפל אותו ל-bytecode, ואז java Main כדי להריץ אותו. עם JDK 11 ומעלה אפשר לדלג על השלב הראשון עבור קובץ יחיד ופשוט להריץ java Main.java ישירות.

מה ההבדל בין javac ל-java?

javac הוא המהדר: הוא קורא את קוד המקור .java ומייצר קובץ .class מלא ב-bytecode. java הוא המפעיל (launcher): הוא מפעיל את ה-JVM ומריץ את ה-bytecode שבקובץ .class. מקמפלים פעם אחת עם javac, ואז מריצים כמה פעמים שרוצים עם java.

למה אני מקבל "could not find or load main class"?

כמעט תמיד כי העברתם ל-java את השם הלא נכון. השתמשו בשם המחלקה, לא בשם הקובץ: java Main, לא java Main.class ולא java Main.java. ודאו גם שאתם בתיקייה שמכילה את Main.class ושם המחלקה תואם בדיוק לשם הקובץ, כולל אותיות גדולות וקטנות.

איור של שפות התכנות ב-Coddy

ללמוד תכנות עם Coddy

להתחיל