Java Language
espressioni
Ricerca…
introduzione
Osservazioni
Per un riferimento sugli operatori che possono essere utilizzati nelle espressioni, vedere Operatori .
Precedenza dell'operatore
Quando un'espressione contiene più operatori, può potenzialmente essere letta in diversi modi. Ad esempio, l'espressione matematica 1 + 2 x 3
potrebbe essere letta in due modi:
- Aggiungi
1
e2
e moltiplica il risultato per3
. Questo dà la risposta9
. Se aggiungessimo le parentesi, sembrerebbe( 1 + 2 ) x 3
. - Aggiungi
1
al risultato di moltiplicare2
e3
. Questo dà la risposta7
. Se aggiungessimo le parentesi, sembrerebbe1 + ( 2 x 3 )
.
In matematica, la convenzione è leggere l'espressione nel secondo modo. La regola generale è che la moltiplicazione e la divisione vengono eseguite prima dell'addizione e della sottrazione. Quando viene usata una notazione matematica più avanzata, o il significato è "autoevidente" (per un matematico addestrato!), O si aggiungono parentesi per disambiguare. In entrambi i casi, l'efficacia della notazione per trasmettere il significato dipende dall'intelligenza e dalla conoscenza condivisa dei matematici.
Java ha le stesse regole chiare su come leggere un'espressione, in base alla precedenza degli operatori che vengono utilizzati.
In generale, a ciascun operatore viene attribuito un valore di precedenza ; vedi la tabella qui sotto.
Per esempio:
1 + 2 * 3
La precedenza di +
è inferiore alla precedenza di *
, quindi il risultato dell'espressione è 7, non 9.
Descrizione | Operatori / costrutti (primario) | Precedenza | Associatività |
---|---|---|---|
Qualifier parentesi Creazione di istanze Accesso al campo Accesso alla matrice Invocazione del metodo Metodo di riferimento | nome . nome ( expr ) new primario . nome primario [ expr ] primario ( expr, ... ) primario :: nome | 15 | Da sinistra a destra |
Incremento della posta | expr ++ , expr -- | 14 | - |
Pre incremento unario Cast 1 | ++ expr, -- expr, + Expr, - espr, ~ espr, ! expr, ( tipo ) expr | 13 | - Da destra a sinistra Da destra a sinistra |
moltiplicativo | * /% | 12 | Da sinistra a destra |
Additivo | + - | 11 | Da sinistra a destra |
Cambio | << >> >>> | 10 | Da sinistra a destra |
relazionale | <> <=> = instanceof | 9 | Da sinistra a destra |
Uguaglianza | ==! = | 8 | Da sinistra a destra |
Bitwise AND | & | 7 | Da sinistra a destra |
OR esclusivo bit per bit | ^ | 6 | Da sinistra a destra |
Bitwise incluso OR | | | 5 | Da sinistra a destra |
AND logico | && | 4 | Da sinistra a destra |
OR logico | || | 3 | Da sinistra a destra |
Condizionale 1 | ? : | 2 | Da destra a sinistra |
assegnazione Lambda 1 | = * = / =% = + = - = << = >> = >>> = & = ^ = | = -> | 1 | Da destra a sinistra |
1 La precedenza dell'espressione lambda è complessa, in quanto può verificarsi anche dopo un cast o come terza parte dell'operatore ternario condizionale.
Espressioni costanti
Un'espressione costante è un'espressione che produce un tipo primitivo o una stringa e il cui valore può essere valutato al momento della compilazione su un valore letterale. L'espressione deve valutare senza generare un'eccezione e deve essere composta solo dal seguente:
Letterali primitivi e stringhe.
Digita i cast ai tipi primitivi o
String
.I seguenti operatori unari:
+
,-
,~
e!
.I seguenti operatori binari:
*
,/
,%
,+
,-
,<<
,>>
,>>>
,<
,<=
,>
,>=
,==
!=
,&
,^
,|
,&&
e||
.L'operatore condizionale ternario
?
:
Espressioni costanti parentesi
Nomi semplici che si riferiscono a variabili costanti. (Una variabile costante è una variabile dichiarata come
final
cui l'espressione di inizializzazione è di per sé un'espressione costante).Nomi qualificati del modulo
<TypeName> . <Identifier>
che si riferisce a variabili costanti.
Si noti che l'elenco precedente esclude ++
e --
, gli operatori di assegnazione, class
e instanceof
, chiamate di metodi e riferimenti a variabili o campi generali.
Espressioni costanti di tipo String
risultato in un "internati" String
, e operazioni a virgola mobile a espressioni costanti vengono valutate con FP-rigide semantica.
Utilizza per le espressioni costanti
Le espressioni costanti possono essere utilizzate (quasi) ovunque sia possibile utilizzare un'espressione normale. Tuttavia, hanno un significato speciale nei seguenti contesti.
Le espressioni costanti sono obbligatorie per le etichette case nelle istruzioni switch. Per esempio:
switch (someValue) {
case 1 + 1: // OK
case Math.min(2, 3): // Error - not a constant expression
doSomething();
}
Quando l'espressione sul lato destro di un compito è un'espressione costante, il compito può eseguire una conversione restringimento primitiva. Ciò è consentito a condizione che il valore dell'espressione costante rientri nell'intervallo del tipo sul lato sinistro. (Vedi JLS 5.1.3 e 5.2 ) Ad esempio:
byte b1 = 1 + 1; // OK - primitive narrowing conversion.
byte b2 = 127 + 1; // Error - out of range
byte b3 = b1 + 1; // Error - not a constant expession
byte b4 = (byte) (b1 + 1); // OK
Quando un'espressione costante viene utilizzata come condizione in una do
, while
o for
, influisce sull'analisi di leggibilità. Per esempio:
while (false) {
doSomething(); // Error - statenent not reachable
}
boolean flag = false;
while (flag) {
doSomething(); // OK
}
(Si noti che questo non si applica if
istruzioni.Il compilatore Java consente al blocco then
o else
di un'istruzione if
di essere irraggiungibile.Questo è l'analogo Java della compilazione condizionale in C e C ++.)
Infine, static final
campi static final
di una classe o di un'interfaccia con inizializzatori di espressioni costanti vengono inizializzati con entusiasmo. Pertanto, è garantito che queste costanti saranno osservate nello stato inizializzato, anche quando c'è un ciclo nel grafico delle dipendenze di inizializzazione della classe.
Per ulteriori informazioni, fare riferimento a JLS 15.28. Espressioni costanti .
Ordine di valutazione dell'espressione
Le espressioni Java sono valutate seguendo le seguenti regole:
- Gli operandi sono valutati da sinistra a destra.
- Gli operandi di un operatore vengono valutati prima dell'operatore.
- Gli operatori vengono valutati in base alla precedenza degli operatori
- Gli elenchi degli argomenti vengono valutati da sinistra a destra.
Semplice esempio
Nell'esempio seguente:
int i = method1() + method2();
l'ordine di valutazione è:
- L'operando di sinistra di
=
operator viene valutato all'indirizzo dii
. - Viene valutato l'operando di sinistra dell'operatore
+
(method1()
). - Viene valutato l'operando destro dell'operatore
+
(method2()
). - L'operazione
+
viene valutata. - L'operazione
=
viene valutata, assegnando il risultato dell'aggiunta ai
.
Notare che se gli effetti delle chiamate sono osservabili, si sarà in grado di osservare che la chiamata al method1
verifica prima della chiamata a method2
.
Esempio con un operatore che ha un effetto collaterale
Nell'esempio seguente:
int i = 1;
intArray[i] = ++i + 1;
l'ordine di valutazione è:
- Viene valutato l'operando di sinistra di
=
operatore. Questo dà l'indirizzo diintArray[1]
. - Il pre-incremento viene valutato. Questo aggiunge
1
ai
e valuta a2
. - Viene valutato l'operando di destra del
+
. - L'operazione
+
viene valutata su:2 + 1
->3
. - L'operazione
=
viene valutata, assegnando3
aintArray[1]
.
Si noti che poiché l'operando di sinistra di =
viene valutato per primo, non è influenzato dall'effetto collaterale della sottoespressione di ++i
.
Riferimento:
Nozioni di base sull'espressione
Le espressioni in Java sono il costrutto principale per fare calcoli. Ecco alcuni esempi:
1 // A simple literal is an expression
1 + 2 // A simple expression that adds two numbers
(i + j) / k // An expression with multiple operations
(flag) ? c : d // An expression using the "conditional" operator
(String) s // A type-cast is an expression
obj.test() // A method call is an expression
new Object() // Creation of an object is an expression
new int[] // Creation of an object is an expression
In generale, un'espressione è costituita dalle seguenti forme:
- Nomi delle espressioni che consistono in:
- Identificatori semplici; ad esempio
someIdentifier
- Identificatori qualificati; es.
MyClass.someField
- Identificatori semplici; ad esempio
- Primari che consistono in:
- letterali; ad es.
1
,1.0
,'X'
,"hello"
,false
enull
- Espressioni letterali di classe; es.
MyClass.class
-
this
e<TypeName> . this
- Espressioni parentesi; es.
( a + b )
- Espressioni di creazione di istanze di classe; es.
new MyClass(1, 2, 3)
- Espressioni di creazione di istanze di array; ad esempio
new int[3]
- Espressioni di accesso al campo; ad esempio
obj.someField
othis.someField
- Espressioni di accesso alla matrice; es.
vector[21]
- Invocazioni di metodi; es.
obj.doIt(1, 2, 3)
- Riferimenti al metodo (Java 8 e versioni successive); ad es.
MyClass::doIt
- letterali; ad es.
- Espressioni di operatore unario; eg
!a
oi++
- Espressioni di operatori binari; es.
a + b
obj == null
- Espressioni dell'operatore ternario; ad esempio
(obj == null) ? 1 : obj.getCount()
- Espressioni Lambda (Java 8 e successive); es.
obj -> obj.getCount()
I dettagli delle diverse forme di espressione possono essere trovati in altri argomenti.
- L'argomento Operatori copre espressioni di operatori unari, binari e ternari.
- L'argomento espressioni Lambda copre espressioni lambda e espressioni di riferimento del metodo.
- L'argomento Classi e oggetti copre le espressioni di creazione di istanze di classe.
- L'argomento Array copre espressioni di accesso alla matrice e espressioni di creazione di istanze di array.
- L'argomento Literals copre i diversi tipi di espressioni letterali.
Il tipo di un'espressione
Nella maggior parte dei casi, un'espressione ha un tipo statico che può essere determinato in fase di compilazione esaminando e le sue sottoespressioni. Questi sono indicati come espressioni stand-alone .
Tuttavia, (in Java 8 e versioni successive) i seguenti tipi di espressioni possono essere espressioni poligonali :
- Espressioni parentesi
- Espressioni di creazione di istanze di classe
- Espressioni di richiamo del metodo
- Espressioni di riferimento del metodo
- Espressioni condizionali
- Espressioni Lambda
Quando un'espressione è un'espressione poli, il suo tipo può essere influenzato dal tipo di destinazione dell'espressione; cioè per cosa viene usato.
Il valore di un'espressione
Il valore di un'espressione è l'assegnazione compatibile con il suo tipo. L'eccezione a questo è quando si è verificato l' inquinamento da cumulo ; ad es. perché gli avvisi di "non sicura conversione" sono stati (inappropriatamente) soppressi o ignorati.
Dichiarazioni di espressione
A differenza di molti altri linguaggi, in genere Java non consente di utilizzare espressioni come istruzioni. Per esempio:
public void compute(int i, int j) {
i + j; // ERROR
}
Poiché il risultato della valutazione di un'espressione come non può essere utilizzato e poiché non può influenzare l'esecuzione del programma in alcun altro modo, i progettisti Java hanno preso la posizione che tale utilizzo è un errore o un errore.
Tuttavia, questo non si applica a tutte le espressioni. Un sottoinsieme di espressioni sono (di fatto) legali come affermazioni. Il set comprende:
- Espressione dell'assegnazione, compresi gli incarichi operativi e gli incarichi.
- Pre e post espressioni di incremento e decremento.
- Chiamate di metodo (
void
o nonvoid
). - Espressioni di creazione di istanze di classe.