Pourquoi «short trente = 3 * 10» est-il une mission légale?

Si short est automatiquement promu en int dans les opérations arithmétiques, alors pourquoi:

 short thirty = 10 * 3; 

Une cession légale à la variable short thirty ?

À son tour, ceci:

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

ainsi que cette:

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

ne comstack pas car l’atsortingbution d’une valeur int à un short n’est pas autorisée sans conversion comme prévu.

Y a-t-il quelque chose de spécial à propos des littéraux numériques?

Parce que le compilateur remplace 10*3 par 30 au moment de la compilation lui même. Donc, effectivement: short thirty = 10 * 3 sont calculés au moment de la compilation.

Essayez de changer ten et three en final short (en les faisant comstackr des constantes de temps) et voyez ce qui se passe: P

Examinez le code d’octet en utilisant javap -v pour les deux versions ( 10*3 et final short ). Vous pourrez voir qu’il y a peu de différence.

Ok, voici la différence de code d’octet pour différents cas.

Cas 1 :

Code Java: main () {short s = 10 * 3; }

Code d’octet:

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

Cas -2:

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

Code d’octet:

  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 

Cas -3:

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

Code octet:

 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 

Dans le cas ci-dessus, 10 et 3 sont tirés des variables locales s1 et s2

Oui, il y a quelque chose de spécial avec le cas littéral: 10 * 3 seront évalués au moment de la compilation . Vous n’avez donc pas besoin d’une conversion explicite (short) pour les littéraux multipliés.

ten * three n’est pas évaluable à la compilation, il faut donc une conversion explicite.

Ce serait différent si ten et three étaient marqués comme final .

La réponse suivante ajoute la section JLS et quelques détails sur ce comportement.

Conformément à l’article JLS §15.2 – Formes d’expressions

Certaines expressions ont une valeur pouvant être déterminée au moment de la compilation. Ce sont des expressions constantes (§15.28).