java short type-promotion

java - ¿Por qué "short treinta=3*10" es una asignación legal?



type-promotion (3)

Si short se promociona automáticamente a int en operaciones aritméticas, entonces por qué es:

short thirty = 10 * 3;

¿Una asignación legal a la variable short thirty ?

A su vez, esto:

short ten = 10; short three = 3; short thirty = ten * three; // DOES NOT COMPILE AS EXPECTED

tan bien como esto:

int ten = 10; int three = 3; short thirty = ten * three; // DOES NOT COMPILE AS EXPECTED

no se compila porque no se permite asignar un valor int a un short sin convertir como se esperaba.

¿Hay algo especial en los literales numéricos?


La siguiente answer agrega la sección JLS y algunos detalles sobre este comportamiento.

Según JLS §15.2 - Formas de expresiones

Algunas expresiones tienen un valor que se puede determinar en tiempo de compilación. Estas son expresiones constantes (§15.28).


Porque el compilador reemplaza 10*3 con 30 en tiempo de compilación . Entonces, efectivamente: short thirty = 10 * 3 se calcula en tiempo de compilación.

Intente cambiar ten y three a final short (haciendo que compilen constantes de tiempo) y vea qué sucede: P

Examine el código de bytes usando javap -v para ambas versiones ( 10*3 y final short ). Podrá ver que hay poca diferencia.

Ok, entonces, aquí está la diferencia de código de byte para diferentes casos.

Caso 1 :

Código Java: main () {short s = 10 * 3; }

Código de bytes:

stack=1, locals=2, args_size=1 0: bipush 30 // directly push 30 into "s" 2: istore_1 3: return

Caso -2:

public static void main(String arf[]) { final short s1= 10; final short s2 = 3; short s = s1*s2; }

Código de bytes:

stack=1, locals=4, args_size=1 0: bipush 10 2: istore_1 3: iconst_3 4: istore_2 5: bipush 30 // AGAIN, push 30 directly into "s" 7: istore_3 8: return

Caso -3:

public static void main(String arf[]) throws Exception { short s1= 10; short s2 = 3; int s = s1*s2; }

Código de bytes:

stack=2, locals=4, args_size=1 0: bipush 10 // push constant 10 2: istore_1 3: iconst_3 // use constant 3 4: istore_2 5: iload_1 6: iload_2 7: imul 8: istore_3 9: return

En el caso anterior, 10 y 3 se toman de las variables locales s1 y s2


Sí, hay algo especial en el caso literal: 10 * 3 se evaluará en tiempo de compilación . Por lo tanto, no necesita una conversión explícita (short) para literales multiplicados.

ten * three no es evaluable en tiempo de compilación, por lo tanto, necesita una conversión explícita.

Sería diferente si ten y three fueran marcados como final .