Metodi in Java
Definisci e chiama metodi in Java — tipi di ritorno, parametri e corpo del metodo — per organizzare codice riutilizzabile.
Un metodo in Java è un blocco di codice con un nome che puoi richiamare da altre parti del programma. I metodi ti permettono di evitare la ripetizione: invece di scrivere lo stesso calcolo o la stessa operazione in cinque righe in tre punti diversi, la inserisci in un metodo e la chiami tre volte.
Hai già visto un metodo in ogni pagina di questo libro — main. Ogni programma Java è semplicemente una classe con almeno un metodo che la JVM sa come avviare. In questa parte del libro vedremo come scrivere i propri metodi.
Anatomia di un metodo
La dichiarazione di un metodo ha fino a cinque parti: modificatori, tipo di ritorno, nome, lista di parametri e corpo.
public static int square(int n) {
return n * n;
}public static— modificatori.publiccontrolla la visibilità;staticsignifica che il metodo appartiene alla classe piuttosto che a un'istanza. Approfondiremo entrambi nelle parti successive; per ora, ogni metodo che scrivi in una classe di utilità di primo livello saràpublic static.int— il tipo di ritorno. Il tipo di valore che il metodo restituisce al chiamante. Usavoidse non restituisce nulla.square— il nome. Per convenzione in lowerCamelCase, e un verbo o una frase verbale che descrive cosa fa il metodo.(int n)— la lista di parametri. Input che il chiamante deve fornire. Ogni parametro è un tipo e un nome.{ ... }— il corpo. Il codice che viene eseguito quando il metodo viene chiamato.
Chiamare un metodo
Una volta definito, chiami un metodo scrivendo il suo nome seguito da (...) con i valori degli argomenti:
int result = square(7); // result is 49
System.out.println(square(3) + square(4)); // 9 + 16 = 25Il valore restituito dal metodo può essere usato come qualsiasi altra espressione — assegnato a una variabile, passato come argomento, stampato, sommato ad altro.
L'istruzione return
return fa due cose: interrompe immediatamente il metodo e invia un valore al chiamante.
public static int absolute(int n) {
if (n < 0) {
return -n;
}
return n;
}Appena viene eseguito return -n, il metodo termina — il secondo return n non viene eseguito. Un metodo con un tipo di ritorno non-void deve restituire un valore in ogni possibile percorso del codice; il compilatore rifiuta di compilare se manca un percorso.
Per i metodi void, puoi usare un return; nudo per uscire anticipatamente, ma non sei obbligato a scriverne uno alla fine:
public static void greet(String name) {
if (name == null) return; // early exit
System.out.println("Hello, " + name);
} // implicit return at the closing braceParametri e argomenti
I nomi nella firma del metodo sono parametri; i valori che passi al momento della chiamata sono argomenti. La distinzione è piccola ma vale la pena capirla bene:
public static int sum(int a, int b) { // a, b are parameters
return a + b;
}
int x = 3, y = 4;
int total = sum(x, y); // x, y are argumentsOgni chiamata ottiene le proprie copie fresche dei parametri. Assegnare ad a all'interno di sum non cambia x nel punto di chiamata. Il capitolo sul passaggio per valore approfondisce i dettagli.
Regole sul tipo di ritorno
L'espressione dopo return deve essere compatibile per assegnazione con il tipo di ritorno dichiarato — stesso tipo, o un tipo che Java può allargare a esso:
public static double half(int n) {
return n / 2.0; // int / double → double, fine
}
public static int half(int n) {
return n / 2.0; // ERROR: double cannot be implicitly narrowed to int
}Se hai davvero bisogno di restringere il tipo, esegui un cast esplicito: return (int)(n / 2.0);.
I metodi possono chiamare altri metodi
Il corpo di un metodo è codice normale — incluse le chiamate ad altri metodi, incluso sé stesso (vedi ricorsione):
public static int square(int n) { return n * n; }
public static int sumOfSquares(int a, int b) {
return square(a) + square(b);
}Costruire metodi piccoli e mirati e comporli è il cuore della scrittura di Java leggibile.
Restituire non è stampare
Un errore comune per i principianti: un metodo che stampa un valore e un metodo che ne restituisce uno non sono intercambiabili. return consegna un valore al chiamante affinché possa usarlo; System.out.println scrive solo testo sulla console e il chiamante non riceve nulla.
public static void printSquare(int n) {
System.out.println(n * n); // shows the result, returns void
}
public static int square(int n) {
return n * n; // gives the result back to the caller
}Puoi memorizzare, sommare o passare il risultato di square, ma int x = printSquare(5); non compila — printSquare restituisce void. Preferisci restituire un valore e lascia che il chiamante decida se stamparlo; mantiene il metodo riutilizzabile.
Overloading: stesso nome, parametri diversi
Java consente a due o più metodi di condividere un nome a patto che le loro liste di parametri differiscano — nel numero di parametri o nei loro tipi. Questo si chiama overloading, e il compilatore sceglie quello giusto in base agli argomenti che passi:
public static int max(int a, int b) { return a > b ? a : b; }
public static double max(double a, double b) { return a > b ? a : b; }
public static int max(int a, int b, int c) { return max(max(a, b), c); }max(3, 9) chiama il primo, max(2.5, 1.5) il secondo e max(4, 1, 7) il terzo. Il solo tipo di ritorno non è sufficiente a distinguere gli overload — contano solo i parametri. Il capitolo sull'overloading dei metodi copre le regole di corrispondenza per intero.
Dove vivono i metodi
Un metodo risiede sempre all'interno di una classe. Non puoi scrivere una funzione di primo livello come puoi fare in JavaScript o Python. La classe è il contenitore; il metodo è uno dei suoi membri. Quindi un file completo con due metodi ha questo aspetto:
public class MathUtils {
public static int square(int n) {
return n * n;
}
public static int cube(int n) {
return n * n * n;
}
}Da main nella stessa classe, li chiameresti come square(5) e cube(2). Da una classe diversa, li qualificheresti: MathUtils.square(5).
Un esempio completo
Cosa c'è dopo
Ora che sai dichiarare e chiamare un metodo, la domanda successiva è come i dati vi fluiscono dentro. Il capitolo sui parametri illustra i dettagli — come gli argomenti si allineano con i parametri, quali tipi sono ammessi e cosa succede quando il chiamante passa oggetti versus primitivi.