Parametri dei metodi Java
Passa valori nei metodi Java tramite parametri e scopri la differenza tra parametri e argomenti.
I parametri sono gli input che un metodo dichiara; gli argomenti sono i valori che fornisci quando lo chiami. Il compilatore verifica che gli argomenti corrispondano ai parametri per tipo e posizione, quindi li consegna al metodo come variabili locali che può usare nel suo corpo.
Questo capitolo illustra nel dettaglio questo passaggio — la sintassi, i tipi che puoi passare e le regole che Java applica per convertire tra di essi.
Dichiarare i parametri
La lista dei parametri di un metodo è una sequenza separata da virgole di coppie Tipo nome:
public static void greet(String name, int times) {
for (int i = 0; i < times; i++) {
System.out.println("Hello, " + name);
}
}Un metodo può dichiarare zero, uno o molti parametri. Ognuno ha bisogno del proprio tipo — non esiste una scorciatoia come int a, b (quello sarebbe int a seguito da b, che non compilerebbe).
Chiamare con gli argomenti
Nel punto di chiamata, passi i valori nello stesso ordine in cui i parametri sono dichiarati:
greet("Ada", 3); // name = "Ada", times = 3Il compilatore verifica due cose:
- Arità — il numero di argomenti corrisponde al numero di parametri.
- Tipi — il tipo di ogni argomento è compatibile con il tipo del parametro corrispondente.
Se uno dei due controlli fallisce, il programma non compilerà. Passare una String dove ci si aspetta un int produrrà un errore come incompatible types: String cannot be converted to int.
I parametri sono variabili locali
All'interno del metodo, ogni parametro si comporta come una variabile locale inizializzata con il valore dell'argomento:
public static int doubleIt(int n) {
n = n * 2; // legal: n is just a local
return n;
}
int x = 5;
int result = doubleIt(x); // result is 10
System.out.println(x); // still 5Riassegnare n all'interno di doubleIt non influisce su x nel punto di chiamata. Ogni chiamata ottiene una propria copia del parametro. Questo è ciò che si intende quando si dice che Java usa il "passaggio per valore" — ogni argomento viene copiato nello slot del parametro. I capitoli successivi trattano le implicazioni, in particolare per gli argomenti oggetto.
Allargamento implicito
Java allarga automaticamente un tipo numerico più piccolo verso uno più grande per corrispondere al parametro:
public static double half(double x) {
return x / 2;
}
int n = 7;
double result = half(n); // n is widened from int to doubleL'allargamento è consentito perché non si perde alcuna informazione. Il restringimento non è implicito — passare un double a un parametro int richiede un cast:
half(7.5); // fine: double argument, double parameter
double d = 3.7;
int i = (int) d; // explicit cast
half(i); // also fineSi applicano le stesse regole di allargamento che valgono per l'assegnazione: byte → short → int → long → float → double, e char → int.
Parametri oggetto
Puoi passare qualsiasi oggetto — String, un array, una classe personalizzata — dichiarando un parametro del tipo riferimento corrispondente:
public static int firstLength(String[] words) {
if (words.length == 0) return 0;
return words[0].length();
}
String[] colors = {"red", "green", "blue"};
System.out.println(firstLength(colors)); // 3L'argomento può essere anche null, nel qual caso il parametro è null e qualsiasi accesso a un campo o chiamata di metodo su di esso lancia NullPointerException. I metodi che accettano riferimenti di solito controllano prima, oppure documentano che null non è permesso.
Passare null
null è compatibile per assegnazione con ogni tipo riferimento, quindi puoi passarlo per qualsiasi parametro oggetto:
greet(null, 1);Se il metodo dereferenzia il parametro (name.length(), name.charAt(0), …), lancia un'eccezione. Un metodo difensivo gestisce null esplicitamente, spesso con una guardia all'inizio:
public static void greet(String name, int times) {
if (name == null) name = "stranger";
for (int i = 0; i < times; i++) {
System.out.println("Hello, " + name);
}
}Parametri final
Puoi contrassegnare un parametro con final per vietarne la riassegnazione all'interno del metodo:
public static int doubleIt(final int n) {
// n = n * 2; // ERROR: cannot assign a value to final variable n
return n * 2;
}Questo non cambia ciò che vede il chiamante — solo se al corpo è consentito riutilizzare lo slot del parametro. Molte guide di stile trattano tutti i parametri come se fossero final anche senza la parola chiave; basta calcolare nuovi valori piuttosto che mutare il parametro.
Ordine di valutazione degli argomenti
Quando scrivi f(a(), b(), c()), gli argomenti vengono valutati da sinistra a destra, tutti prima che f venga chiamata. Se a() lancia un'eccezione, b() e c() non vengono mai eseguiti.
public static int log(String label, int value) {
System.out.println(label + " = " + value);
return value;
}
public static int sum(int a, int b, int c) {
return a + b + c;
}
sum(log("a", 1), log("b", 2), log("c", 3));
// prints:
// a = 1
// b = 2
// c = 3Questo determinismo è diverso da C e C++; in Java l'ordine è fisso e prevedibile.
Un esempio pratico
Cosa c'è dopo
Ora sai come i dati entrano in un metodo. A volte vuoi due metodi con lo stesso nome ma input diversi — ad esempio, uno che accetta un int e un altro che accetta una String. Java ti permette di scrivere entrambi con l'overloading dei metodi.