W3docs

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 .java e produce file .class.
  • java — il launcher. Carica la JVM, trova una classe per nome ed esegue il suo metodo main.
  • 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 --version

Compilare 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.java

Se non ci sono errori, vedrai un nuovo file nella stessa directory chiamato Greeting.class. Quello è il bytecode. Eseguilo:

java Greeting
Hello 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 out dice a javac di mettere i file .class generati nella directory out/ (ricreando la struttura delle directory del package).
  • -cp out dice a java di cercare le classi nel classpath out/.
  • 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.java

Il launcher compila in memoria ed esegue il risultato immediatamente — nessun file .class viene scritto su disco. È ideale per script veloci ed esercizi del libro.

Nota

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> /exit

Non 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 javacjava sul nostro server ogni volta che premi Run:

java— editable, runs on the server

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, un import mancante 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, oppure javac è 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.

Esercizi

Pratica
Quale comando compila Greeting.java in bytecode?
Quale comando compila Greeting.java in bytecode?
Was this page helpful?