Recherche…


Introduction

Les expressions en Java sont la construction principale pour effectuer des calculs.

Remarques

Pour obtenir une référence sur les opérateurs pouvant être utilisés dans les expressions, voir Opérateurs .

Priorité de l'opérateur

Lorsqu'une expression contient plusieurs opérateurs, elle peut potentiellement être lue de différentes manières. Par exemple, l'expression mathématique 1 + 2 x 3 peut être lue de deux manières:

  1. Ajoutez 1 et 2 et multipliez le résultat par 3 . Cela donne la réponse 9 . Si nous ajoutions des parenthèses, cela ressemblerait à ( 1 + 2 ) x 3 .
  2. Ajouter 1 au résultat de la multiplication par 2 et 3 . Cela donne la réponse 7 . Si nous ajoutions des parenthèses, cela ressemblerait à 1 + ( 2 x 3 ) .

En mathématiques, la convention est de lire l'expression de la seconde manière. La règle générale est que la multiplication et la division se font avant l'addition et la soustraction. Lorsqu'une notation mathématique plus avancée est utilisée, soit la signification est "évidente" (pour un mathématicien qualifié!), Soit des parenthèses sont ajoutées pour désambiguïser. Dans les deux cas, l'efficacité de la notation pour transmettre le sens dépend de l'intelligence et de la connaissance partagée des mathématiciens.

Java a les mêmes règles claires sur la façon de lire une expression, en fonction de la priorité des opérateurs utilisés.

En général, chaque opérateur reçoit une valeur de priorité ; voir le tableau ci-dessous.

Par exemple:

  1 + 2 * 3

La priorité de + est inférieure à la priorité de * , donc le résultat de l’expression est 7, et non 9.

La description Opérateurs / constructions (primaires) Priorité Associativité
Qualificatif
Parenthèses
Création d'instance
Accès sur le terrain
Accès aux tableaux
Invocation de méthode
Méthode de référence
nom . prénom
( expr )
new
primaire . prénom
primaire [ expr ]
primary ( expr, ... )
primaire :: nom
15 De gauche à droite
Incrément de poste expr ++ , expr -- 14 -
Pré incrémentation
Unary
Cast 1
++ expr, -- expr,
+ Expr, - expr, ~ expr, ! expr,
( type ) expr
13 -
De droite à gauche
De droite à gauche
Multiplicatif * /% 12 De gauche à droite
Additif + - 11 De gauche à droite
Décalage << >> >>> dix De gauche à droite
Relationnel <> <=> = instanceof 9 De gauche à droite
Égalité ==! = 8 De gauche à droite
Bitwise AND Et 7 De gauche à droite
Bitwise exclusive OU ^ 6 De gauche à droite
Bitwise inclus OU | 5 De gauche à droite
Logique ET && 4 De gauche à droite
OU logique || 3 De gauche à droite
Conditionnel 1 ? : 2 De droite à gauche
Affectation
Lambda 1
= * = / =% = + = - = << = >> = >>> = & = ^ = | =
->
1 De droite à gauche

1 La priorité de l'expression lambda est complexe, car elle peut également apparaître après un transtypage ou en tant que troisième partie de l'opérateur ternaire conditionnel.

Expressions constantes

Une expression constante est une expression qui donne un type primitif ou une chaîne et dont la valeur peut être évaluée au moment de la compilation en un littéral. L'expression doit être évaluée sans lancer une exception et doit être composée uniquement des éléments suivants:

  • Littéraux primitifs et de chaînes.

  • Tapez sur les types primitifs ou sur String .

  • Les opérateurs unaires suivants: + , - , ~ et ! .

  • Les opérateurs binaires suivants: * , / , % , + , - , << , >> , >>> , < , <= , > , >= , == != , & , ^ , | , && et || .

  • L'opérateur conditionnel ternaire ? : .

  • Expressions constantes entre parenthèses.

  • Noms simples faisant référence à des variables constantes. (Une variable constante est une variable déclarée comme final lorsque l'expression d'initialisation est elle-même une expression constante.)

  • Noms qualifiés du formulaire <TypeName> . <Identifier> qui fait référence à des variables constantes.

Notez que la liste ci-dessus exclut ++ et -- , les opérateurs d'affectation, class et instanceof , les appels de méthodes et les références aux variables générales ou aux champs.

Les expressions constantes de type String résultat dans un « interné » String et opérations en virgule flottante dans les expressions constantes sont évaluées avec la sémantique FP stricte.

Utilisations pour les expressions constantes

Des expressions constantes peuvent être utilisées (à peu près) partout où une expression normale peut être utilisée. Cependant, ils ont une signification particulière dans les contextes suivants.

Les expressions constantes sont requises pour les étiquettes de cas dans les instructions switch. Par exemple:

switch (someValue) {
case 1 + 1:            // OK
case Math.min(2, 3):   // Error - not a constant expression
    doSomething();
}

Lorsque l'expression sur le côté droit d'une affectation est une expression constante, l'affectation peut effectuer une conversion restrictive primitive. Ceci est autorisé à condition que la valeur de l'expression constante se situe dans la plage du type sur le côté gauche. (Voir JLS 5.1.3 et 5.2 ) Par exemple:

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

Lorsqu'une expression constante est utilisée comme condition dans un do , while ou for , cela affecte l'analyse de lisibilité. Par exemple:

while (false) {
    doSomething();           // Error - statenent not reachable
}
boolean flag = false;
while (flag) {
    doSomething();           // OK
}

(Notez que ceci ne s'applique pas aux instructions if . Le compilateur Java permet que le bloc then ou else d'une instruction if soit inaccessible. Il s'agit de l'analogue Java de la compilation conditionnelle en C et C ++.)

Enfin, static final champs static final une classe ou d'une interface avec des initialiseurs d'expression constante sont initialisés avec impatience. Ainsi, il est garanti que ces constantes seront observées dans l'état initialisé, même s'il existe un cycle dans le graphe de dépendance d'initialisation de classe.

Pour plus d'informations, reportez-vous à JLS 15.28. Expressions constantes

Ordre d'évaluation des expressions

Les expressions Java sont évaluées selon les règles suivantes:

  • Les opérandes sont évalués de gauche à droite.
  • Les opérandes d'un opérateur sont évalués avant l'opérateur.
  • Les opérateurs sont évalués en fonction de la priorité des opérateurs
  • Les listes d'arguments sont évaluées de gauche à droite.

Exemple simple

Dans l'exemple suivant:

int i = method1() + method2();

l'ordre d'évaluation est:

  1. L'opérande gauche = opérateur est évalué à l'adresse i .
  2. L'opérande gauche de l'opérateur + ( method1() ) est évalué.
  3. Le bon opérande de l'opérateur + ( method2() ) est évalué.
  4. L'opération + est évaluée.
  5. L'opération = est évaluée, affectant le résultat de l'addition à i .

Notez que si les effets des appels sont observables, vous pourrez observer que l'appel à la method1 se produit avant l'appel à la method2 .

Exemple avec un opérateur qui a un effet secondaire

Dans l'exemple suivant:

int i = 1;
intArray[i] = ++i + 1;

l'ordre d'évaluation est:

  1. L'opérande gauche de l'opérateur = est évalué. Cela donne l'adresse de intArray[1] .
  2. Le pré-incrément est évalué. Cela ajoute 1 à i et évalue à 2 .
  3. L'opérande de droite du + est évalué.
  4. L'opération + est évaluée à: 2 + 1 -> 3 .
  5. L'opération = est évaluée, affectant 3 à intArray[1] .

Notez que puisque l'opérande gauche de = est évalué en premier, il n'est pas influencé par l'effet secondaire de la sous-expression ++i .

Référence:

Les bases de l'expression

Les expressions en Java sont la construction principale pour effectuer des calculs. Voici quelques exemples:

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

En général, une expression comprend les formes suivantes:

  • Noms d'expression qui consistent en:
    • Identifiants simples; par exemple, un someIdentifier
    • Identificateurs qualifiés; par exemple MyClass.someField
  • Primaires qui consistent en:
    • Littéraux; par exemple 1 , 1.0 , 'X' , "hello" , false et null
    • Expressions littérales de classe; par exemple MyClass.class
    • this et <TypeName> . this
    • Expressions entre parenthèses; par exemple ( a + b )
    • Expressions de création d'instance de classe; par exemple, new MyClass(1, 2, 3)
    • Expressions de création d'instance de tableau; p.ex. new int[3]
    • Expressions d'accès au champ; par exemple obj.someField ou this.someField
    • Expressions d'accès aux tableaux; par exemple, vector[21]
    • Invocations de méthodes; p.ex. obj.doIt(1, 2, 3)
    • Références de méthode (Java 8 et versions ultérieures) Par exemple, MyClass::doIt
  • Les expressions d'opérateur unaire; par exemple !a ou i++
  • Les expressions d'opérateur binaire; par exemple a + b ou obj == null
  • Les expressions d'opérateurs ternaires; par exemple (obj == null) ? 1 : obj.getCount()
  • Expressions lambda (Java 8 et versions ultérieures); obj -> obj.getCount()

Les détails des différentes formes d'expressions peuvent être trouvés dans d'autres sujets.

  • La rubrique Opérateurs couvre les expressions opérateur unaires, binaires et ternaires.
  • La rubrique Expressions Lambda couvre les expressions lambda et les expressions de référence de méthode.
  • La rubrique Classes et objets couvre les expressions de création d'instance de classe.
  • La rubrique Arrays couvre les expressions d'accès au tableau et les expressions de création d'instances de tableaux.
  • La rubrique Literals couvre les différents types d'expressions littérales.

Le type d'une expression

Dans la plupart des cas, une expression a un type statique qui peut être déterminé au moment de la compilation en examinant et ses sous-expressions. Celles-ci sont appelées expressions autonomes .

Cependant, (en Java 8 et versions ultérieures) les types d’expressions suivantes peuvent être des expressions poly :

  • Expressions parenthèses
  • Expressions de création d'instance de classe
  • Expressions d'appel de méthode
  • Expressions de référence de méthode
  • Expressions conditionnelles
  • Expressions lambda

Lorsqu'une expression est une expression poly, son type peut être influencé par le type de cible de l'expression. c'est-à-dire à quoi sert-il?

La valeur d'une expression

La valeur d'une expression est une affectation compatible avec son type. La seule exception à cette règle est la pollution par tas ; Par exemple, les avertissements de "conversion non sécurisée" ont été (de manière inappropriée) supprimés ou ignorés.

Déclarations d'expression

Contrairement à beaucoup d’autres langages, Java ne permet généralement pas d’utiliser des expressions comme instructions. Par exemple:

public void compute(int i, int j) {
    i + j;   // ERROR
}

Étant donné que le résultat de l'évaluation d'une expression comme ne peut pas être utilisé et que cela ne peut pas affecter l'exécution du programme d'une autre manière, les concepteurs Java ont considéré qu'un tel usage était une erreur ou une erreur.

Cependant, cela ne s'applique pas à toutes les expressions. Un sous-ensemble d'expressions est (en fait) légal sous forme d'énoncés. L'ensemble comprend:

  • Expression d'affectation, y compris les affectations d' opération et de conversion.
  • Pré et post incrémenter et décrémenter les expressions.
  • Appels de méthode ( void ou non void ).
  • Expressions de création d'instance de classe.


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow