Hasta hoy, pensé que, por ejemplo:
i += j;
Era solo un atajo para:
i = i + j;
Pero si intentamos esto:
int i = 5;
long j = 8;
Entonces i = i + j;no se 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)?
java
casting
operators
variable-assignment
assignment-operator
Honza Brabec
fuente
fuente

i+=(long)j;incluso compilará bien.i += (int) f;lanza f antes de la suma, por lo que no es equivalente.(int) i += f;arroja el resultado después de la asignación, tampoco equivalente. no habría lugar para colocar un elenco que significaría que desea emitir el valor después de agregar, pero antes de la asignación.Respuestas:
Como siempre con estas preguntas, el JLS tiene la respuesta. En este caso, §15.26.2 Operadores de asignación compuesta . Un extracto:
Un ejemplo citado de §15.26.2
En otras palabras, su suposición es correcta.
fuente
i+=jcompila como me revisé, pero daría como resultado una pérdida de precisión ¿verdad? Si ese es el caso, ¿por qué no permite que ocurra también en i = i + j? ¿Por qué molestarnos allí?i += j), es más seguro asumir que se desea la pérdida de precisión en comparación con el otro caso (i = i + j)E1 op= E2 is equivalent to E1 = (T)((E1) op (E2))entonces eso es algo así como la conversión de tipos implícita hacia abajo (desde largo hasta int). Mientras que en i = i + j, tenemos que hacerlo explícitamente, es decir, proporcionar la(T)parte enE1 = ((E1) op (E2))¿No es así?Un buen ejemplo de este casting es usar * = o / =
o
o
o
fuente
A;)ch += 32= DMuy buena pregunta La especificación del lenguaje Java confirma su sugerencia.
fuente
double->floatcomo una ampliación, sobre la base de que los valores de tipofloatidentifican números reales menos específicamente que los de tipodouble. Si se vedoublecomo una dirección postal completa yfloatcomo un código postal de 5 dígitos, es posible satisfacer una solicitud de un código postal dada una dirección completa, pero no es posible especificar con precisión una solicitud de una dirección completa dada solo un código postal . Convertir una dirección de calle en un código postal es una operación con pérdida, pero ...float->doublees equivalente a convertir el código postal 90210 de EE. UU. Con "US Post Office, Beverly Hills CA 90210".Si,
básicamente cuando escribimos
el compilador convierte esto a
Acabo de comprobar el
.classcódigo del archivo.Realmente es algo bueno saber
fuente
debe convertir desde
longaintexplicitlyen caso dei = i + lque se compile y dé la salida correcta. me gustao
pero en caso de
+=que simplemente funcione bien porque el operador realiza implícitamente el tipo de conversión de tipo de variable derecha a tipo de variable izquierda, por lo que no es necesario emitir explícitamente.fuente
intse lleva a cabo después de la+. El compilador (debe?) Lanza una advertencia si realmente ha desechado ellongqueint.El problema aquí implica la conversión de tipos.
Cuando agregas int y long,
Pero
+=está codificado de tal manera que sí lo hace.i=(int)(i+m)fuente
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 de forma segura al tipo de la variable en el lado izquierdo de la asignación. Por lo tanto, podemos asignar con seguridad:
Lo mismo no funcionará al revés. Por ejemplo, no podemos convertir automáticamente un largo a int porque el primero requiere más almacenamiento que el segundo y, en consecuencia, se puede perder información. Para forzar tal conversión debemos llevar a cabo una conversión explícita.
Tipo - Conversión
fuente
longes 2 veces más grande quefloat.floatno puede retener todos losintvalores posibles , ydoubleno puede retener todos loslongvalores posibles .double d=33333333+1.0f;sin quejas, aunque el resultado 33333332.0 probablemente no sea lo que se pretendía (por cierto, la respuesta aritméticamente correcta de 33333334.0f sería representable comofloatoint).A veces, tal pregunta se puede hacer en una entrevista.
Por ejemplo, cuando escribes:
No hay encasillamiento automático. En C ++ no habrá ningún error al compilar el código anterior, pero en Java obtendrá algo así
Incompatible type exception.Para evitarlo, debe escribir su código de esta manera:
fuente
opuso en C ++ con su uso en Java. Siempre me gusta ver estas curiosidades y creo que contribuyen con algo a la conversación que a menudo se puede omitir.La principal diferencia es que con
a = a + bno hay ningún tipo de conversión de texto, por lo que el compilador se enoja con usted por no hacerlo. Pero cona += blo que realmente está haciendo es convertirba un tipo compatiblea. Entonces si lo hacesLo que realmente estás haciendo es:
fuente
Punto sutil aquí ...
Hay un tipo de letra implícito para
i+jcuandojes un doble yies un int. Java SIEMPRE convierte un número entero en un doble cuando hay una operación entre ellos.Para aclarar
i+=jdóndeies un número entero yjun doble se puede describir comoVer: esta descripción del casting implícito
Es posible que desee encasillado
ja(int)en este caso, para mayor claridad.fuente
int someInt = 16777217; float someFloat = 0.0f; someInt += someFloat;. Agregar cero asomeIntno debería afectar su valor, pero promocionarsomeIntafloatpuede cambiar su valor.La especificación del lenguaje Java define
E1 op= E2ser equivalente aE1 = (T) ((E1) op (E2))dondeTes un tipo deE1yE1se evalúa una vez .Esa es una respuesta técnica, pero puede que se pregunte por qué es así. Bueno, consideremos el siguiente programa.
¿Qué imprime este programa?
¿Adivinaste 3? Lástima, este programa no se compilará. ¿Por qué? Bueno, sucede que la adición de bytes en Java se define para devolver un
int. Esto, creo que fue porque la máquina virtual Java no define operaciones de byte para guardar en códigos de byte (después de todo, hay un número limitado de ellas), el uso de operaciones enteras es un detalle de implementación expuesto en un lenguaje.Pero si
a = a + bno funciona, eso significaríaa += bque nunca funcionaría para bytes si seE1 += E2definiera como talE1 = E1 + E2. Como muestra el ejemplo anterior, ese sería el caso. Como un truco para hacer que el+=operador funcione para bytes y cortos, hay un elenco implícito involucrado. No es un gran truco, pero durante el trabajo de Java 1.0, el enfoque se centró en liberar el lenguaje para empezar. Ahora, debido a la compatibilidad con versiones anteriores, este truco introducido en Java 1.0 no se pudo eliminar.fuente