Come compilare ed eseguire un programma Java
Usa javac per compilare file .java in bytecode .class e il launcher java per eseguirli sulla JVM.
Un programma Java attraversa due fasi prima di produrre un output. Prima il compilatore trasforma i tuoi file sorgente .java in bytecode neutro rispetto alla piattaforma (file .class). Poi la JVM carica quel bytecode e lo esegue. Comprendere entrambe le fasi ti permette di ragionare sugli errori del classpath, sul packaging e sui casi limite particolari che a volte si presentano.
Questo capitolo illustra la toolchain — javac, java e jshell — e la struttura dei file che gli strumenti si aspettano.
La toolchain
Quando installi il JDK ottieni tre comandi che userai continuamente:
javac— il compilatore Java. Prende i file sorgente.javae produce file.class.java— il launcher. Carica la JVM, trova una classe per nome ed esegue il suo metodomain.jshell— un REPL interattivo (read-eval-print loop) per provare frammenti di codice senza scrivere un programma completo. Aggiunto in Java 9.
Puoi verificare che siano disponibili eseguendo ciascuno con -version:
javac -version
java -version
jshell --versionCompilare un singolo file sorgente
Supponi di avere questo file salvato come Greeting.java:
public class Greeting {
public static void main(String[] args) {
System.out.println("Hello from javac!");
}
}Compilalo:
javac Greeting.javaSe non ci sono errori, vedrai un nuovo file nella stessa directory chiamato Greeting.class. Quello è il bytecode. Eseguilo:
java GreetingHello from javac!Nota che si passa il nome della classe, non il nome del file. java Greeting.class è sbagliato; lo è anche java Greeting.java.
Compilare un programma con package
I programmi reali sono organizzati in package che rispecchiano la struttura delle directory. Una classe dichiarata come package com.example.greet; deve trovarsi in com/example/greet/.
project/
└── src/
└── com/example/greet/
└── Greeting.java// src/com/example/greet/Greeting.java
package com.example.greet;
public class Greeting {
public static void main(String[] args) {
System.out.println("Hello with packages!");
}
}Dalla directory project/, compila ed esegui con il nome di classe pienamente qualificato:
javac -d out src/com/example/greet/Greeting.java
java -cp out com.example.greet.Greeting-d outdice ajavacdi mettere i file.classgenerati nella directoryout/(ricreando la struttura delle directory del package).-cp outdice ajavadi cercare le classi nel classpathout/.com.example.greet.Greetingè il nome di classe pienamente qualificato — il package, un punto e la classe.
In pratica useresti uno strumento di build (Maven o Gradle, trattati più avanti in questo libro) per fare tutto questo. Ma sapere cosa fanno internamente aiuta quando qualcosa va storto.
Modalità file sorgente (programmi a file singolo)
Da Java 11 puoi saltare javac completamente per i programmi a file singolo:
java Greeting.javaIl launcher compila in memoria ed esegue il risultato immediatamente — nessun file .class viene scritto su disco. È ideale per script veloci ed esercizi del libro.
La modalità file sorgente funziona solo quando il programma si trova in un singolo file .java. Nel momento in cui suddividi il codice su due file sorgente, torna a usare javac (o uno strumento di build) per compilarli insieme.
jshell — il REPL interattivo
jshell ti permette di digitare espressioni e istruzioni Java una riga alla volta, proprio come un REPL Python o Node:
$ jshell
| Welcome to JShell -- Version 21.0.4
| For an introduction type: /help intro
jshell> int x = 21
x ==> 21
jshell> int y = 21
y ==> 21
jshell> x + y
$3 ==> 42
jshell> System.out.println("Hello!")
Hello!
jshell> /exitNon hai bisogno di una classe, di un metodo main o persino di punti e virgola per le espressioni semplici. È un ottimo modo per esplorare la libreria standard senza dover configurare un progetto.
Eseguire dall'IDE
Ogni IDE Java — IntelliJ, Eclipse, VS Code — invoca javac e java dietro le quinte quando fai clic su Run. L'IDE gestisce anche il classpath, mostra gli errori del compilatore inline e visualizza l'output del programma in un pannello della console. Non devi usare la riga di comando, ma sapere cosa fa l'IDE rende il debug dei problemi di build molto più rapido.
Un esempio dal vivo
Il blocco eseguibile qui sotto passa attraverso lo stesso ciclo javac → java sul nostro server ogni volta che premi Run:
Modifica il codice, premi Run e il server compila il tuo sorgente modificato e stampa qualsiasi cosa produca il programma.
Errori di compilazione comuni
Alcuni errori che incontrerai spesso:
class Greeting is public, should be declared in a file named Greeting.java— il nome del file e il nome della classe pubblica devono corrispondere esattamente.error: cannot find symbol— di solito un errore di battitura, unimportmancante o una classe che non è nel classpath.';' expected— un punto e virgola mancante alla fine di un'istruzione.error: package x.y.z does not exist— la directory del package non è nel classpath, oppurejavacè stato puntato alla radice sorgente sbagliata.
In caso di dubbio, leggi il messaggio di errore — i messaggi diagnostici di javac sono insolitamente chiari.
Cosa c'è dopo
Con la toolchain a portata di mano, la parte successiva del libro inizia con il linguaggio stesso: Variabili Java, Tipi di dati e il resto delle basi della sintassi.