relacionales programacion operadores operador ejemplos asignacion aritmeticos java casting operators variable-assignment assignment-operator

programacion - ¿Por qué los operadores de asignación compuesta+=,-=,*=,/= de Java no requieren conversión?



operadores de asignacion programacion (10)

Hasta hoy, pensé que por ejemplo:

i += j;

Solo fue un atajo para:

i = i + j;

Pero si intentamos esto:

int i = 5; long j = 8;

Entonces i = i + j; no compilará pero i += j; se compilará bien.

¿Significa que, de hecho, i += j; es un atajo para algo como esto i = (type of i) (i + j) ?


A veces, tal pregunta se puede hacer en una entrevista.

Por ejemplo, cuando escribes:

int a = 2; long b = 3; a = a + b;

No hay encasillamiento automático. En C ++ no habrá ningún error al compilar el código anterior, pero en Java obtendrá algo como la Incompatible type exception .

Así que para evitarlo, debes escribir tu código así:

int a = 2; long b = 3; a += b;// No compilation error or any exception due to the auto typecasting


Como siempre con estas preguntas, el JLS tiene la respuesta. En este caso, §15.26.2 Operadores de asignación de compuestos . Un extracto:

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.

Un ejemplo citado de §15.26.2

[...] el siguiente código es correcto:

short x = 3; x += 4.6;

y da como resultado que x tenga el valor 7 porque es equivalente a:

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

En otras palabras, tu suposición es correcta.


El problema aquí involucra el casting de tipos.

Cuando añades int y long,

  1. El objeto int se convierte en largo y ambos se agregan y se obtiene el objeto largo.
  2. pero el objeto largo no se puede convertir implícitamente a int. Entonces, tienes que hacer eso explícitamente.

Pero += está codificado de tal manera que hace conversión de tipo. i=(int)(i+m)


En Java, las conversiones de tipo se realizan automáticamente cuando el tipo de expresión en el lado derecho de una operación de asignación se puede promover con seguridad al tipo de la variable en el lado izquierdo de la asignación. Así podemos asignar con seguridad:

byte -> short -> int -> long -> float -> double.

Lo mismo no funcionará al revés. Por ejemplo, no podemos convertir automáticamente un largo en un int porque el primero requiere más almacenamiento que el segundo y, en consecuencia, la información puede perderse. Para forzar tal conversión debemos realizar una conversión explícita.
Tipo - Conversión


La principal diferencia es que con a = a + b , no hay encasillamiento continuo, por lo que el compilador se enoja contigo por no encasillarlo. Pero con a += b , lo que realmente está haciendo es encasillar b a un tipo compatible con a . Así que si lo haces

int a=5; long b=10; a+=b; System.out.println(a);

Lo que realmente estás haciendo es:

int a=5; long b=10; a=a+(int)b; System.out.println(a);


Muy buena pregunta. La especificación del lenguaje Java confirma tu sugerencia.

Por ejemplo, el siguiente código es correcto:

short x = 3; x += 4.6;

y da como resultado que x tenga el valor 7 porque es equivalente a:

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


Punto sutil aquí ...

Hay un encasillamiento implícito para i+j cuando j es doble e i es un int. Java SIEMPRE convierte un entero en un doble cuando hay una operación entre ellos.

Para aclarar i+=j donde i es un número entero y j es un doble, se puede describir como

i = <int>(<double>i + j)

Ver: esta descripción de casting implícito.

Es posible que desee encasillar j a (int) en este caso para mayor claridad.


Sí,

básicamente cuando escribimos

i += l;

el compilador convierte esto a

i = (int)(i + l);

Acabo de comprobar el código del archivo .class .

Realmente una buena cosa para saber


Un buen ejemplo de este casting es usar * = o / =

byte b = 10; b *= 5.7; System.out.println(b); // prints 57

o

byte b = 100; b /= 2.5; System.out.println(b); // prints 40

o

char ch = ''0''; ch *= 1.1; System.out.println(ch); // prints ''4''

o

char ch = ''A''; ch *= 1.5; System.out.println(ch); // prints ''a''


debe emitir de long a int explicitly en caso de que i = i + l luego compilará y dará el resultado correcto. me gusta

i = i + (int)l;

o

i = (int)((long)i + l); // this is what happens in case of += , dont need (long) casting since upper casting is done implicitly.

pero en el caso de += simplemente funciona bien porque el operador realiza implícitamente el tipo de conversión del tipo de la variable derecha al tipo de la variable izquierda, por lo que no es necesario realizar la conversión explícita.