Java Language
Expresiones
Buscar..
Introducción
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:
- Suma
1
y2
y multiplica el resultado por3
. Esto da la respuesta9
. Si agregáramos paréntesis, esto se vería como( 1 + 2 ) x 3
. - Suma
1
al resultado de multiplicar2
y3
. Esto da la respuesta7
. Si agregáramos paréntesis, esto se vería como1 + ( 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:
- El operando izquierdo de
=
operator se evalúa en la dirección dei
. - Se evalúa el operando izquierdo del operador
+
(method1()
). - Se evalúa el operando derecho del operador
+
(method2()
). - Se evalúa la operación
+
. - Se evalúa la operación
=
, asignando el resultado de la suma ai
.
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:
- Se evalúa el operando izquierdo de
=
operator. Esto da la dirección deintArray[1]
. - Se evalúa el pre-incremento. Esto agrega
1
ai
, y evalúa a2
. - El operando de la derecha del
+
es evaluado. - La operación
+
se evalúa como:2 + 1
->3
. - Se evalúa la operación
=
, asignando3
aintArray[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
- Identificadores simples; por ejemplo,
- Primarias que consisten en:
- Literales; por ejemplo,
1
,1.0
,'X'
,"hello"
,false
ynull
- 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
othis.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
- Literales; por ejemplo,
- Expresiones de operador unario; por ejemplo
!a
i++
- Expresiones de operador binarias; por ejemplo,
a + b
uobj == 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 novoid
). - Expresiones de creación de instancia de clase.