Buscar..


Introducción

Las expresiones en Java son la construcción primaria para hacer cálculos.

Observaciones

Para obtener una referencia sobre los operadores que se pueden usar en expresiones, consulte Operadores .

Precedencia del operador

Cuando una expresión contiene múltiples operadores, potencialmente puede leerse de diferentes maneras. Por ejemplo, la expresión matemática 1 + 2 x 3 se puede leer de dos maneras:

  1. Suma 1 y 2 y multiplica el resultado por 3 . Esto da la respuesta 9 . Si agregáramos paréntesis, esto se vería como ( 1 + 2 ) x 3 .
  2. Suma 1 al resultado de multiplicar 2 y 3 . Esto da la respuesta 7 . Si agregáramos paréntesis, esto se vería como 1 + ( 2 x 3 ) .

En matemáticas, la convención es leer la expresión de la segunda manera. La regla general es que la multiplicación y la división se realizan antes de la suma y la resta. Cuando se usa una notación matemática más avanzada, el significado es "evidente por sí mismo" (¡para un matemático capacitado!), O se agregan paréntesis para desambiguar. En cualquier caso, la efectividad de la notación para transmitir significado depende de la inteligencia y el conocimiento compartido de los matemáticos.

Java tiene las mismas reglas claras sobre cómo leer una expresión, en función de la precedencia de los operadores que se utilizan.

En general, a cada operador se le asigna un valor de precedencia ; Vea la tabla de abajo.

Por ejemplo:

  1 + 2 * 3

La precedencia de + es menor que la precedencia de * , por lo que el resultado de la expresión es 7, no 9.

Descripción Operadores / constructos (primarios) Precedencia Asociatividad
Índice
Paréntesis
Creación de instancias
Acceso al campo
Acceso a la matriz
Invocación de método
Referencia del método
nombre . nombre
( expr )
new
primaria . nombre
primaria [ expr ]
primaria ( expr, ... )
primario :: nombre
15 De izquierda a derecha
Post Incremento expr ++ , expr -- 14 -
Pre incremento
Unario
Reparto 1
++ expr, -- expr,
+ Expr, - expr, ~ expr, ! expr
( tipo ) expr
13 -
De derecha a izquierda
De derecha a izquierda
Multiplicativa * /% 12 De izquierda a derecha
Aditivo + - 11 De izquierda a derecha
Cambio << >> >>> 10 De izquierda a derecha
Relacional <> <=> = instanceof 9 De izquierda a derecha
Igualdad ==! = 8 De izquierda a derecha
Y a nivel de bit Y 7 De izquierda a derecha
Exclusivo bitwise O ^ 6 De izquierda a derecha
Bitwise inclusive O | 5 De izquierda a derecha
Y lógico && 4 De izquierda a derecha
O lógico || 3 De izquierda a derecha
Condicional 1 ? : 2 De derecha a izquierda
Asignación
Lambda 1
= * = / =% = + = - = << = >> = >>> = & = ^ = | =
->
1 De derecha a izquierda

1 La precedencia de expresión Lambda es compleja, ya que también puede ocurrir después de una conversión, o como la tercera parte del operador ternario condicional.

Expresiones constantes

Una expresión constante es una expresión que produce un tipo primitivo o una cadena, y cuyo valor puede evaluarse en tiempo de compilación a un literal. La expresión debe evaluar sin lanzar una excepción, y debe estar compuesta de solo lo siguiente:

  • Literales primitivos y de cuerdas.

  • Tipo de conversión a tipos primitivos o String .

  • Los siguientes operadores unarios: + , - , ~ y ! .

  • Los siguientes operadores binarios: * , / , % , + , - , << , >> , >>> , < , <= , > , >= , == != , & , ^ , | , && y || .

  • ¿El operador condicional ternario ? : .

  • Expresiones constantes entre paréntesis.

  • Nombres simples que se refieren a variables constantes. (Una variable constante es una variable declarada como final donde la expresión inicializadora es en sí misma una expresión constante).

  • Nombres calificados del formulario <TypeName> . <Identifier> que se refiere a variables constantes.

Tenga en cuenta que la lista anterior excluye ++ y -- , los operadores de asignación, class y instanceof , llamadas de método y referencias a variables generales o campos.

Las expresiones constantes de tipo String resultar en una "internados" String , y operaciones de punto flotante en expresiones constantes se evalúan con la semántica FP-estrictas.

Usos para expresiones constantes

Las expresiones constantes se pueden usar (casi) en cualquier lugar donde se pueda usar una expresión normal. Sin embargo, tienen un significado especial en los siguientes contextos.

Las expresiones constantes son necesarias para las etiquetas de casos en las declaraciones de cambio. Por ejemplo:

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

Cuando la expresión en el lado derecho de una asignación es una expresión constante, la asignación puede realizar una conversión de estrechamiento primitivo. Esto se permite siempre que el valor de la expresión constante esté dentro del rango del tipo en el lado izquierdo. (Ver JLS 5.1.3 y 5.2 ) Por ejemplo:

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

Cuando se usa una expresión constante como condición en un do , while o for , entonces afecta el análisis de legibilidad. Por ejemplo:

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

(Tenga en cuenta que esto no se aplica a las sentencias if . El compilador de Java permite que se pueda acceder al bloque then o else de una sentencia if . Este es el análogo de Java de la compilación condicional en C y C ++).

Finalmente, static final campos static final en una clase o interfaz con inicializadores de expresiones constantes se inicializan con entusiasmo. Por lo tanto, se garantiza que estas constantes se observarán en el estado inicializado, incluso cuando hay un ciclo en el gráfico de dependencia de inicialización de clase.

Para obtener más información, consulte JLS 15.28. Expresiones constantes .

Orden de evaluación de expresiones

Las expresiones de Java se evalúan siguiendo las siguientes reglas:

  • Los operandos se evalúan de izquierda a derecha.
  • Los operandos de un operador se evalúan antes que el operador.
  • Los operadores son evaluados de acuerdo a la precedencia del operador.
  • Las listas de argumentos se evalúan de izquierda a derecha.

Ejemplo simple

En el siguiente ejemplo:

int i = method1() + method2();

El orden de evaluación es:

  1. El operando izquierdo de = operator se evalúa en la dirección de i .
  2. Se evalúa el operando izquierdo del operador + ( method1() ).
  3. Se evalúa el operando derecho del operador + ( method2() ).
  4. Se evalúa la operación + .
  5. Se evalúa la operación = , asignando el resultado de la suma a i .

Tenga en cuenta que si los efectos de las llamadas son observables, podrá observar que la llamada a method1 ocurre antes de la llamada a method2 .

Ejemplo con un operador que tiene un efecto secundario

En el siguiente ejemplo:

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

El orden de evaluación es:

  1. Se evalúa el operando izquierdo de = operator. Esto da la dirección de intArray[1] .
  2. Se evalúa el pre-incremento. Esto agrega 1 a i , y evalúa a 2 .
  3. El operando de la derecha del + es evaluado.
  4. La operación + se evalúa como: 2 + 1 -> 3 .
  5. Se evalúa la operación = , asignando 3 a intArray[1] .

Tenga en cuenta que dado que el operando de la izquierda de = se evalúa primero, no está influenciado por el efecto secundario de la subexpresión ++i .

Referencia:

Conceptos básicos de expresión

Las expresiones en Java son la construcción primaria para hacer cálculos. Aquí hay unos ejemplos:

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 general, una expresión consta de las siguientes formas:

  • Nombres de expresiones que consisten en:
    • Identificadores simples; por ejemplo, someIdentifier
    • Identificadores calificados; por ejemplo, MyClass.someField
  • Primarias que consisten en:
    • Literales; por ejemplo, 1 , 1.0 , 'X' , "hello" , false y null
    • Expresiones literales de clase; por ejemplo, MyClass.class
    • this y <TypeName> . this
    • Expresiones entre paréntesis; por ejemplo ( a + b )
    • Expresiones de creación de instancia de clase; por ejemplo, new MyClass(1, 2, 3)
    • Expresiones de creación de instancia de matriz; por ejemplo, new int[3]
    • Expresiones de acceso al campo; por ejemplo, obj.someField o this.someField
    • Expresiones de acceso a la matriz; por ejemplo, vector[21]
    • Invocaciones de método; por ejemplo, obj.doIt(1, 2, 3)
    • Referencias de métodos (Java 8 y posteriores); por ejemplo, MyClass::doIt
  • Expresiones de operador unario; por ejemplo !a i++
  • Expresiones de operador binarias; por ejemplo, a + b u obj == null
  • Expresiones del operador ternario; por ejemplo (obj == null) ? 1 : obj.getCount()
  • Expresiones Lambda (Java 8 y posteriores); por ejemplo, obj -> obj.getCount()

Los detalles de las diferentes formas de expresiones se pueden encontrar en otros temas.

  • El tema Operadores cubre expresiones de operador unarias, binarias y ternarias.
  • El tema de expresiones Lambda cubre expresiones lambda y expresiones de referencia de métodos.
  • El tema Clases y objetos abarca expresiones de creación de instancia de clase.
  • El tema Arrays cubre expresiones de acceso a la matriz y expresiones de creación de instancia de matriz.
  • El tema Literales cubre los diferentes tipos de expresiones literales.

El tipo de expresión

En la mayoría de los casos, una expresión tiene un tipo estático que se puede determinar en tiempo de compilación mediante el examen y sus subexpresiones. Estos se conocen como expresiones independientes .

Sin embargo, (en Java 8 y posteriores) los siguientes tipos de expresiones pueden ser expresiones poli :

  • Expresiones entre paréntesis
  • Expresiones de creación de instancia de clase
  • Expresiones de invocación de métodos
  • Expresiones de referencia del método
  • Expresiones condicionales
  • Expresiones lambda

Cuando una expresión es una expresión poli, su tipo puede verse influido por el tipo de destino de la expresión; Es decir, para qué se está utilizando.

El valor de una expresión

El valor de una expresión es la asignación compatible con su tipo. La excepción a esto es cuando ha ocurrido la contaminación del montón ; por ejemplo, porque las advertencias de "conversión insegura" se han suprimido o ignorado (de manera inadecuada).

Declaraciones de Expresión

A diferencia de muchos otros lenguajes, Java generalmente no permite que las expresiones se usen como declaraciones. Por ejemplo:

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

Dado que el resultado de evaluar una expresión como no se puede usar, y como no puede afectar la ejecución del programa de ninguna otra manera, los diseñadores de Java tomaron la posición de que tal uso es un error o está equivocado.

Sin embargo, esto no se aplica a todas las expresiones. Un subconjunto de expresiones son (de hecho) legales como declaraciones. El conjunto comprende:

  • Expresión de asignación, incluidas las asignaciones de operaciones y se convierte en .
  • Expresiones pre y post incremento y decremento.
  • Las llamadas de método ( void o no void ).
  • Expresiones de creación de instancia de clase.


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow