variable español error cannot java initialization conditional final

español - ¿Por qué el compilador de Java no entiende que esta variable siempre se inicializa?



javac error cannot find symbol (3)

Como parte del objetivo de la portabilidad, hay un conjunto muy específico de reglas para lo que un compilador debe aceptar y lo que debe rechazar. Esas reglas permiten y requieren solo una forma limitada de análisis de flujo al determinar si una variable se asigna definitivamente en su uso.

Consulte el Capítulo 16 de la Especificación del lenguaje Java . Asignación definitiva

La regla crítica es la de 16.2.7. Si las declaraciones , el caso "if (e) S". La regla para ser asignado definitivamente se expande a:

V se asigna después de si (e) S si, y solo si, V se asigna después de S y V se asigna después de e cuando es falso.

y es la V relevante. Está sin asignar antes de la instrucción if. De hecho, se asigna después de S , y = {y = -1;} pero no hay nada que lo asigne cuando x> 100 es falso.

Por lo tanto, y no se asigna definitivamente después de la sentencia if.

Un análisis de flujo más completo determinaría que la condición x> 100 siempre es verdadera, pero el JLS requiere que el compilador rechace el programa basándose en estas reglas específicas.

La variable final está bien. La regla es en realidad:

"Es un error de tiempo de compilación si se asigna una variable final a menos que esté definitivamente sin asignar (§16) inmediatamente antes de la asignación".

La declaración la deja definitivamente sin asignar, e incluso el análisis de flujo limitado puede determinar que x todavía no se ha asignado en la asignación.

class Foo{ public static void main(String args[]){ final int x=101; int y; if(x>100){ y=-1; } System.out.println(y); } }

El compilador de Java entiende la condición de la sentencia if siempre es verdadera y, por lo tanto, y siempre se inicializará. No hay error de compilación, como se esperaba.

class Bar{ public static void main(String args[]){ final int x; x=101; int y; if(x>100){ y=-1; } System.out.println(y); } }

Pero cuando rompo la declaración y la inicialización de x en dos líneas, el compilador no parece darse cuenta de que la condición es siempre verdadera y y siempre se inicializará.

final int x; x=101; byte b; b=x; System.out.println(b);

Lo mismo sucede aquí y el compilador da un error de pérdida de precisión.

final int x=101; byte b; b=x; System.out.println(b);

Nuevamente, el compilador puede entender que x está dentro del rango de b.


Lo que has hecho para la variable x en el segundo código se llama variable final en blanco . Si una variable final no se inicializa cuando se declara, entonces se conoce como una variable final en blanco.

Muchos desarrolladores de Java piensan que el valor de una variable final se conoce en el tiempo de compilación. Esto NO siempre es cierto. Se dice que el valor de una variable final en blanco NO se conoce en el momento de la compilación. Por lo tanto, su segundo código le dará un error de compilación. El compilador puede ver que ha inicializado la variable final x , pero compilar no sabe su valor. Así que el compilador no puede resolver la sentencia if. Por eso piensa que la variable y no está inicializada.

Puedes leer más sobre las variables finales de Java here .


Tiene que ver con la forma en que el compilador determina si una instrucción se ejecutará o no. Se define en el JLS # 16 :

Cada variable local y cada campo final en blanco deben tener un valor asignado definitivamente cuando se produce cualquier acceso a su valor.

En su caso, el compilador no puede determinar que y definitivamente ha sido asignado y le da un error. Esto se debe a que necesitaría determinar que la condición siempre es verdadera y eso solo es posible si la condición en el if es una expresión constante .

JLS # 15.28 define expresiones constantes :

Una expresión constante en tiempo de compilación es una expresión que denota un valor de tipo primitivo o una cadena que no se completa de manera abrupta y se compone utilizando solo lo siguiente:

  • [...]
  • Nombres simples (§6.5.6.1) que se refieren a variables constantes (§4.12.4).

El JLS # 4.12.4 define variables constantes como:

Una variable de tipo primitivo o tipo String, que es final e inicializa con una expresión constante de tiempo de compilación, se denomina variable constante.

En tu caso, final int x = 101; es una variable constante pero final int x; x = 101; final int x; x = 101; no es.