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+=j
compila 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->float
como una ampliación, sobre la base de que los valores de tipofloat
identifican números reales menos específicamente que los de tipodouble
. Si se vedouble
como una dirección postal completa yfloat
como 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->double
es 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
.class
código del archivo.Realmente es algo bueno saber
fuente
debe convertir desde
long
aint
explicitly
en caso dei = i + l
que 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
int
se lleva a cabo después de la+
. El compilador (debe?) Lanza una advertencia si realmente ha desechado ellong
queint
.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
long
es 2 veces más grande quefloat
.float
no puede retener todos losint
valores posibles , ydouble
no puede retener todos loslong
valores 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 comofloat
oint
).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
op
uso 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 + b
no hay ningún tipo de conversión de texto, por lo que el compilador se enoja con usted por no hacerlo. Pero cona += b
lo que realmente está haciendo es convertirb
a 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+j
cuandoj
es un doble yi
es un int. Java SIEMPRE convierte un número entero en un doble cuando hay una operación entre ellos.Para aclarar
i+=j
dóndei
es un número entero yj
un doble se puede describir comoVer: esta descripción del casting implícito
Es posible que desee encasillado
j
a(int)
en este caso, para mayor claridad.fuente
int someInt = 16777217; float someFloat = 0.0f; someInt += someFloat;
. Agregar cero asomeInt
no debería afectar su valor, pero promocionarsomeInt
afloat
puede cambiar su valor.La especificación del lenguaje Java define
E1 op= E2
ser equivalente aE1 = (T) ((E1) op (E2))
dondeT
es un tipo deE1
yE1
se 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 + b
no funciona, eso significaríaa += b
que nunca funcionaría para bytes si seE1 += E2
definiera 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