Pregunta

Para mi sorpresa, resulta que el siguiente código se compilará sin siquiera advertencias:

public void test()
{
    int value = 2000000000;
    long increment = 1000000000;
    value += increment;
}

Mientras que esto genera un error en tiempo de compilación, como era de esperar:

public void test()
{
    int value = 2000000000;
    long increment = 1000000000;
    value = value + increment;
}

Lo revisé y, de hecho, el JLS (sección 15.26.2) dice lo siguiente:

Una expresión de asignación compuesta de la forma E1 OP = E2 es equivalente a E1 = (t) ((E1) OP (E2)), donde t es el tipo de E1, excepto que E1 se evalúa solo una vez.

Esto me parece ridículo.¿Por qué sintieron la necesidad de elegir explícitamente aquí?Parece que la conversión automática de tipos habría manejado la ampliación de todos modos, y es casi seguro que un estrechamiento automático de esta manera dará como resultado un desbordamiento de enteros.

¿Fue útil?

Solución

aquí es unoExplicación:

Cuando realiza una asignación (el fragmento de código de primer código), Java hace cumplir el tipo de tipo porque el LHS y RHS pueden ser muy independientes entre sí.

Pero el operador compuesto es más como un operador incremental.El += Modifica el valor de la variable. involucrado, en lugar de asignar un nuevo Valor a la variable.Cuando modificas un byte, espera un byte como el resultado.Para hacer la vida más fácil, Java hace una conversión de tipo implícito para operadores compuestos porque son modificadores.

Otros consejos

Los operadores de asignación compuesta están especificados por JLS (15.26.2) como sigue:

"Una expresión de asignación compuesta de la forma E1 op= E2 es equivalente a

      E1 = (T)((E1) op (E2))`, 

donde T es el tipo de E1, excepto que E1 se evalúa sólo una vez."

En este caso E1 es del tipo int E2 es de tipo long, y op es +.Entonces esto es equivalente a:

value = (int)(value + increment);

La adición de un int y un long da un long que luego se devuelve a un int antes de la asignación.Todo eso está bien, por lo tanto, no hay errores de compilación.

La diferencia entre esto y la asignación simple (es decir, value = value + increment;), es que la tarea simple no tiene encasillamiento.


OK entonces por qué ¿Lo definieron así?

Creo que la razón es hacer que ejemplos como este funcionen:

    byte b = ...
    b += 1;

Sin el encasillamiento, b += 1 Sería un error de compilación y necesitarías escribirlo como:

    b += (byte) 1;

Este enlace ha analizado el problema que ha superado.

Comportamiento variable para la posible pérdida de precisión

para evitar sorpresas desagradables, no Utilice operadores de asignación compuesta en Variables de tipo byte, corto, o carbonizarse.Al usar la asignación compuesta Operadores en las variables de tipo int, Asegúrate de que la expresión en el lado derecho no es de tipo largo, flotando, o doble.Al usar el compuesto Operadores de asignación en variables de Tipo flotante, asegúrese de que la expresión en el lado derecho no es de tipo doble.Estas reglas son suficientes para evitar que el compilador genere Pelos de estrechamiento peligroso.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top