A cosa servono gli operatori
Gli operatori sono i simboli che combinano valori per calcolarne di nuovi. Li usi già in modo informale (+ somma, > confronta), e Java li raggruppa in alcune famiglie: aritmetici, di confronto, logici, di assegnazione e un paio di operatori speciali come l'incremento e il ternario.
La maggior parte degli operatori prende due valori (uno prima e uno dopo il simbolo) e produce un risultato. Il punto è sapere di che tipo è quel risultato e in che ordine vengono applicati: è qui che chi inizia inciampa.
Operatori aritmetici
I cinque operatori aritmetici lavorano sui numeri: +, -, *, / e % (resto).
L'operatore % è il resto della divisione: 17 % 5 vale 2 perché il 5 sta tre volte nel 17 con il resto di 2. È lo strumento di tutti i giorni per verificare la divisibilità: n % 2 == 0 è il controllo standard per sapere se n è pari.
Nota anche che + ha un doppio ruolo: con i numeri somma, ma con una String da una delle due parti unisce il testo.
La prima riga si legge da sinistra a destra: "Total: " + 3 è già una stringa, quindi il 4 viene aggiunto come testo. Metti il calcolo tra parentesi quando vuoi che venga eseguito per primo.
La trappola della divisione intera
È la sorpresa più comune in assoluto. Quando entrambi gli operandi di / sono interi, Java esegue una divisione intera e scarta la parte decimale: non arrotonda, tronca verso lo zero.
Per ottenere un risultato decimale, rendi double almeno un operando: scrivilo con .0 oppure fai il cast di un lato con (double). Scrivere (double)(5 / 2) non aiuta, perché la divisione intera 5 / 2 è già avvenuta prima del cast: devi convertire un operando, non il risultato.
Operatori di confronto
Gli operatori di confronto fanno una domanda sì/no e restituiscono un boolean. Sono sei: ==, !=, <, >, <=, >=.
Attento alla differenza tra = (assegnazione, "metti qui questo valore") e == (confronto, "sono uguali?"). Confonderli è un bug classico.
Un'avvertenza importante: == confronta i riferimenti degli oggetti, non il loro contenuto. Per le stringhe usa .equals().
Usa == per i tipi primitivi come int e boolean, e .equals() ogni volta che confronti il contenuto di oggetti come le stringhe.
Operatori logici
Gli operatori logici combinano valori booleani: && (and), || (or) e ! (not). Servono a esprimere condizioni come "ha l'età giusta e ha un biglietto".
&& e || sono a corto circuito: Java smette di valutare appena la risposta è certa. Con &&, se il lato sinistro è false il lato destro non viene mai controllato; con ||, se il lato sinistro è true il lato destro viene saltato. Non è solo un'ottimizzazione: puoi sfruttarlo per la sicurezza:
if (text != null && text.length() > 0) { ... }
Se text è null, il lato sinistro è false e text.length() non viene mai chiamato, evitando una NullPointerException. Se inverti l'ordine, il programma va in crash.
Assegnazione e incremento
= assegna, ma Java ha anche assegnazioni composte che uniscono un'operazione all'assegnazione: +=, -=, *=, /=, %=. E ++ / -- aggiungono o sottraggono uno.
++ esiste in due versioni: postfissa (count++) restituisce il vecchio valore e poi incrementa; prefissa (++count) incrementa prima e poi restituisce il nuovo valore. La differenza conta solo quando usi il risultato nella stessa espressione:
Quando ++ è su una riga da solo, postfisso o prefisso non fa differenza: scegli quello che si legge meglio e non infilare incrementi in espressioni più grandi.
L'operatore ternario
Il ternario condition ? a : b è un if/else compatto che produce un valore: se la condizione è true vale a, altrimenti b.
È perfetto per brevi assegnazioni del tipo "questo o quello". Evita di annidare ternari dentro altri ternari: diventano illeggibili in fretta, e un semplice if/else è più chiaro.
Precedenza e parentesi
Gli operatori si applicano in un ordine fisso, un po' come in matematica: *, /, % hanno precedenza su + e -, che hanno precedenza sui confronti, che a loro volta hanno precedenza su && e poi su ||.
Non serve memorizzare tutta la tabella. Quando un'espressione mescola famiglie diverse o devi fermarti a capire l'ordine, aggiungi le parentesi: non costano niente e rendono evidente l'intenzione a chi leggerà dopo.
Prossima pagina: type casting
Diverse trappole di questa pagina, come la divisione intera o il mescolare int e double, dipendono dai tipi. Convertire deliberatamente un tipo numerico in un altro si chiama casting, ed è l'argomento della prossima pagina.
Domande frequenti
Cosa fa l'operatore % in Java?
% è l'operatore del resto (modulo): dà ciò che avanza dopo una divisione intera. 7 % 3 vale 1 e 10 % 2 vale 0. È il modo standard per verificare la divisibilità (n % 2 == 0 significa che n è pari) e per riportare un valore dentro un intervallo.
Perché 5 / 2 dà 2 in Java invece di 2.5?
Quando entrambi gli operandi sono interi, / esegue una divisione intera e scarta la parte decimale, quindi 5 / 2 vale 2, non 2.5. Per ottenere 2.5 almeno un operando deve essere un double: scrivi 5.0 / 2, 5 / 2.0 oppure fai il cast di un lato con (double) 5 / 2.
Qual è la differenza tra == ed equals() in Java?
== confronta i tipi primitivi per valore, ma per gli oggetti (compresa String) confronta i riferimenti, cioè se sono lo stesso oggetto in memoria. Per confrontare il contenuto degli oggetti usa .equals(). Confrontare due stringhe con == può restituire false anche quando il testo è uguale, quindi per le stringhe usa sempre "a".equals(b).