Quelle est la différence entre les deux lignes suivantes de code java?

Excusez moi pour mon ignorance. Je ne pouvais pas comprendre la différence entre les lignes de code apparemment similaires suivantes.

  1. final int num1 = 1;
  2. final int num2; num2 = 2;

Qu’est-ce qui fait que le num2 n’est pas éligible pour un cas de commutation constant?

  switch (expression) { case num1: System.out.println("Case A"); case num2: System.out.println("Case B"); } 

Nous allons à la spécification du langage Java. Les étiquettes de case d’une instruction switch sont définies comme suit:

 SwitchLabel: case ConstantExpression : case EnumConstantName : default : 

Votre variable num ne fait pas référence à un nom de constante enum , ignorons-le. Qu’est-ce qu’un ConstantExpressions ? Le JLS le définit à nouveau

Une expression constante au moment de la compilation est une expression désignant une valeur de type primitif ou une Ssortingng qui ne se termine pas brutalement. Elle est composée uniquement à l’aide des éléments suivants:

  • Littéraux de type primitif et littéraux de type Ssortingng
  • […]
  • Noms simples (§6.5.6.1) qui font référence à des variables constantes (§4.12.4).

Donc, la primitive int valeur 2 est une expression constante. Vous pourriez faire

 switch { case 2: } 

Maintenant, nous voulons connaître la relation avec l’utilisation de la variable final et constante .

Une final vide est une variable final dont la déclaration manque d’initialiseur. […]

Une variable de type primitif ou de type Ssortingng , final et initialisée avec une expression constante au moment de la compilation (§15.28), est appelée une variable constante .

Donc, cette dernière citation fait référence à une variable final non vide , c’est-à-dire. celui qui a un initialiseur.

Alors

 final int num1 = 1; 

est une variable constante.

Et

 final int num2; num2 = 2; 

n’est pas et ne peut donc pas être utilisé dans une étiquette de case .

Donc, pour répondre à votre question: num1 est une constante de compilation, le compilateur peut donc le remplacer par 1 :

 switch(whatever) { case num1: // will produce same bytecode as case 1: // num1 was replaced by comstackr } 

Le compilateur ne peut pas supposer la même chose à propos de num2 , comme expliqué avec un exemple simple ici

Notez que vous auriez le même problème avec num1 , l’avez-vous initialisé avec une valeur non constante, par exemple: int num1 = new Random().nextInt();

en num1 vous l’initialisez tout de suite, en num2 vous ne le faites pas tout de suite, vous lui atsortingbuez sa valeur plus tard