Pregunta

En Java, cuando lo hace

int b = 0;
b = b + 1.0;

Se obtiene una posible pérdida de precisión de error. Pero por qué es que si lo hace

int b = 0;
b += 1.0;

No hay ningún error?

¿Fue útil?

Solución

Esto se debe a b += 1.0; es equivalente a b = (int) ((b) + (1.0));. Los estrechamiento de conversión primitiva (JLS 5.1.3) se oculta en la operación de asignación compuesto.

JLS 15.26. 2 operadores de asignación compuestos (JLS Tercera Edición):

  

A expresión de asignación compuesto 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.

     

Por ejemplo, el siguiente código es correcto:

short x = 3;
x += 4.6;
     

y resultados en x que tiene la 7 valor porque es equivalente a:

short x = 3;
x = (short)(x + 4.6);

Esto también explica por qué las compilaciones de código siguiente:

byte b = 1;
int x = 5;
b += x; // compiles fine!

Pero esto no:

byte b = 1;
int x = 5;
b = b + x; // DOESN'T COMPILE!

Es necesario convertir explícitamente en este caso:

byte b = 1;
int x = 5;
b = (byte) (b + x); // now it compiles fine!

Vale la pena señalar que el reparto implícito en las asignaciones de compuestos es el tema de Puzzle 9: Tweedledum del libro maravilloso Puzzlers Java . Éstos son algunos extracto del libro (editado ligeramente por razones de brevedad):

  

Muchos programadores piensan que x += i; es simplemente una abreviatura de x = x + i;. Esto no es del todo cierto: si el tipo del resultado es más amplio que el de la variable, las preformas operador de asignación compuesto un estrechamiento conversión primitiva silencioso

.      

Para evitar sorpresas desagradables, no utilice operadores de asignación compuestos en variables de tipo byte, short, o char. Al utilizar operadores de asignación compuestos en variables de tipo int, asegurarse de que la expresión en el lado derecho no es de tipo long, float, o double. Al utilizar operadores de asignación compuestos en variables de tipo float, asegurarse de que la expresión en el lado derecho no es de tipo double. Estas reglas son suficientes para evitar que el compilador de generar moldes de estrechamiento peligrosas.

     

Para los diseñadores del lenguaje, es probablemente un error para los operadores de asignación compuestos para generar moldes invisibles; asignaciones compuestos donde la variable tiene un tipo más estrecho que el resultado del cálculo probablemente debería ser ilegal.

El último párrafo es digno de mención: C # es mucho más estricta en este sentido (véase C # Language Specification 7.13.2 asignación Compuesto ).

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