Ricerca…


introduzione

Le espressioni in Java sono il costrutto principale per fare calcoli.

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:

  1. Aggiungi 1 e 2 e moltiplica il risultato per 3 . Questo dà la risposta 9 . Se aggiungessimo le parentesi, sembrerebbe ( 1 + 2 ) x 3 .
  2. Aggiungi 1 al risultato di moltiplicare 2 e 3 . Questo dà la risposta 7 . Se aggiungessimo le parentesi, sembrerebbe 1 + ( 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 è:

  1. L'operando di sinistra di = operator viene valutato all'indirizzo di i .
  2. Viene valutato l'operando di sinistra dell'operatore + ( method1() ).
  3. Viene valutato l'operando destro dell'operatore + ( method2() ).
  4. L'operazione + viene valutata.
  5. L'operazione = viene valutata, assegnando il risultato dell'aggiunta a i .

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 è:

  1. Viene valutato l'operando di sinistra di = operatore. Questo dà l'indirizzo di intArray[1] .
  2. Il pre-incremento viene valutato. Questo aggiunge 1 a i e valuta a 2 .
  3. Viene valutato l'operando di destra del + .
  4. L'operazione + viene valutata su: 2 + 1 -> 3 .
  5. L'operazione = viene valutata, assegnando 3 a intArray[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
  • Primari che consistono in:
    • letterali; ad es. 1 , 1.0 , 'X' , "hello" , false e null
    • 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 o this.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
  • Espressioni di operatore unario; eg !a o i++
  • 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 non void ).
  • Espressioni di creazione di istanze di classe.


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow