Operatori Logici e Operatori Relazionali in Java
- Operatori Relazionali: confrontano due valori e restituiscono un valore booleano che indica la relazione tra di essi.
- Operatori Logici: operano su valori booleani e combinano risultati logici per produrre un nuovo valore booleano.
- Corto Circuito: gli operatori
&&
e||
valutano il secondo operando solo se necessario, migliorando l'efficienza e prevenendo errori.
Operatori relazionali
Gli operatori relazionali determinano la relazione che un operando ha rispetto all'altro. In particolare, stabiliscono uguaglianza e ordinamento. Gli operatori relazionali sono mostrati di seguito:
Operatore | Risultato |
---|---|
== |
Uguale a |
!= |
Diverso da |
> |
Maggiore di |
< |
Minore di |
>= |
Maggiore o uguale a |
<= |
Minore o uguale a |
L'esito di queste operazioni è un valore booleano. Gli operatori relazionali sono usati più di frequente nelle espressioni che controllano l'istruzione if
e le varie istruzioni di ciclo.
Qualsiasi tipo in Java, inclusi interi, numeri a virgola mobile, caratteri e booleani, può essere confrontato utilizzando il test di uguaglianza ==
e il test di disuguaglianza !=
. In Java l'uguaglianza è indicata con due segni di uguale, non con uno solo (un singolo segno di uguale è l'operatore di assegnazione). Soltanto i tipi numerici possono essere confrontati tramite gli operatori di ordinamento; cioè solo operandi interi, a virgola mobile e carattere possono essere messi a confronto per stabilire quale sia maggiore o minore.
Come indicato, il risultato prodotto da un operatore relazionale è un valore booleano. Per esempio, il seguente frammento di codice è perfettamente valido:
int a = 4;
int b = 1;
boolean c = a < b;
In questo caso il risultato di a<b
(che è false
) viene memorizzato in c
.
Per chi proviene dal C/C++, occorre prestare attenzione a quanto segue. In C/C++ sono molto comuni istruzioni di questo tipo:
int completato;
// ...
if(!completato) ... // Valido in C/C++
if(completato) ... // ma non in Java.
In Java tali istruzioni devono essere scritte così:
if(completato == 0) ... // Stile Java.
if(completato != 0) ...
Il motivo risiede nel fatto che Java non definisce true
e false
allo stesso modo del C/C++. In quest'ultimo, true
è qualunque valore diverso da zero e false
è zero. In Java, invece, true
e false
sono valori non numerici che non si riferiscono a zero o non-zero; di conseguenza, per verificare la condizione di zero o non-zero è necessario impiegare esplicitamente uno o più operatori relazionali.
Operatori logici booleani
Gli operatori logici booleani mostrati di seguito agiscono solo su operandi di tipo boolean
. Tutti gli operatori binari combinano due valori booleani per produrre un valore booleano risultante.
Operatore | Risultato |
---|---|
& |
AND logico |
| |
OR logico |
^ |
XOR logico (OR esclusivo) |
|| |
OR a corto circuito |
&& |
AND a corto circuito |
! |
NOT logico unario |
&= |
Assegnazione AND |
|= |
Assegnazione OR |
^= |
Assegnazione XOR |
Operatore | Risultato |
---|---|
== |
Uguale a |
!= |
Diverso da |
?: |
If-then-else ternario |
L'operatore logico !
inverte lo stato booleano: !true == false
e !false == true
. La tabella seguente mostra l'effetto di ciascuna operazione logica:
A |
B |
A || B |
A && B |
A ^ B |
!A |
---|---|---|---|---|---|
Falso | Falso | Falso | Falso | Falso | Vero |
Vero | Falso | Vero | Falso | Vero | Falso |
Falso | Vero | Vero | Falso | Vero | Vero |
Vero | Vero | Vero | Vero | Falso | Falso |
Ecco un programma quasi identico all'esempio visto nella lezione sugli operatori bitwise, ma che opera su valori logici booleani invece che su bit binari:
// Dimostrare gli operatori logici booleani.
class LogicaBool {
public static void main(String[] args) {
boolean a = true;
boolean b = false;
boolean c = a | b;
boolean d = a & b;
boolean e = a ^ b;
boolean f = (!a & b) | (a & !b);
boolean g = !a;
System.out.println(" a = " + a);
System.out.println(" b = " + b);
System.out.println(" a|b = " + c);
System.out.println(" a&b = " + d);
System.out.println(" a^b = " + e);
System.out.println("!a&b|a&!b = " + f);
System.out.println(" !a = " + g);
}
}
Dopo l'esecuzione si può osservare che le stesse regole logiche si applicano ai valori booleani così come ai bit. L'output mostra che la rappresentazione in forma di stringa di un valore booleano in Java è uno dei due letterali true
oppure false
:
a = true
b = false
a|b = true
a&b = false
a^b = true
!a&b|a&!b = true
!a = false
Corto Circuito degli operatori Logici
Java fornisce due operatori booleani particolarmente interessanti, non presenti in alcuni altri linguaggi. Si tratta delle versioni secondarie degli operatori AND e OR, comunemente noti come operatori logici short-circuit (a corto circuito). L'operatore ||
produce true
quando A
è true
, indipendentemente dal valore di B
. In modo analogo, l'operatore &&
produce false
quando A
è false
, qualunque sia B
. Usando le forme ||
e &&
invece delle forme |
e &
, Java evita di valutare l'operando destro quando il risultato dell'espressione può essere determinato dal solo operando sinistro. Ciò è particolarmente utile quando l'operando destro dipende dal valore di quello sinistro per funzionare correttamente. Per esempio, il frammento seguente sfrutta la valutazione a corto circuito per garantire che un'operazione di divisione sia valida prima di essere eseguita:
if (denominatore != 0 && numeratore / denominatore > 10)
Poiché viene impiegata la forma &&
, non vi è rischio di eccezione a run-time se denominatore
vale zero. Se la stessa riga fosse scritta usando la versione singola &
, entrambi i lati verrebbero valutati, generando un'eccezione a run-time quando denominatore
è zero.
Nella pratica è consuetudine usare le forme a corto circuito di AND e OR nelle situazioni che coinvolgono logica booleana, riservando le versioni a carattere singolo esclusivamente alle operazioni bit-wise. Vi sono tuttavia eccezioni a tale regola. Ad esempio:
if(c == 1 & e++ < 100) d = 100;
In questo caso l'uso di &
assicura che l'operazione di incremento sia applicata a e
indipendentemente dal fatto che c
sia uguale a 1
o meno.
Terminologia ufficiale
La specifica formale di Java si riferisce agli operatori a corto circuito con i termini conditional-and e conditional-or.