2012-01-18 9 views
13

Acabo de hacer un pequeño cambio de código para silenciar una advertencia de FindBugs que requiere mover algún código a una clase interna anónima. Para acceder a algunas variables, tuve que declararlas como final. Así que este es el fragmento de código después del cambio:Declarando variables locales como definitivas sin inicializador y asignándolas en if-statement

final File[] libPath; // libPath is final but assignment takes place later 
if (libraryPath != null) { 
    libPath = pathToFiles(libraryPath); 
} else { 
    libPath = new File[0]; 
} 

Esto compila bien con el lenguaje ajustado a Java 6 en Eclipse actual (versión 3.7.1). Sin embargo, estoy bastante seguro de que esto solía dar un error en alguna versión anterior. Parece que el compilador acepta este constructo cuando puede determinar que lo habrá.

Mi pregunta es: ¿esto es legal en Java 6 o es algo que ahora funciona debido a un efecto secundario del soporte de Java 7 que se está agregando a eclipse 3.7.1? Hemos visto tales efectos secundarios con cierto uso de genéricos que funciona en 3.7.1 pero no compilados en 3.7.0.

Respuesta

8

Esto fue permitido y funcionó bien desde Java 1.1 y no le causará problemas con otros compiladores o IDEs.

Es un comportamiento estándar en Java y se especificó formalmente por primera vez en el Java Language Specification 2nd Edition.

+0

De las muchas respuestas correctas que apuntan a la especificación del idioma, aceptaré esta ya que fue la primera en responder. – Axel

0

Está bien. La variable no tiene un valor, y se asigna solo una vez. Fallaría si le ha dado inicialmente un valor de null.

0

me gustaría sugerir fuertemente utilizar este código en su lugar:

final File[] libPath = ibraryPath == null ? new File[0] : pathToFiles(libraryPath); 

Esto no depende de ninguna versión del compilador, pero es 100% apoyado Java con un significado claro.

+1

Algunos dirían que también es más complicado de leer;) – ShiDoiSi

+0

Es una cuestión de gusto, tal vez. Pero lo prefiero, porque las expresiones son expresiones y no se convierten innecesariamente en declaraciones. Esta es también una construcción del lenguaje que está presente en casi todos los idiomas desde al menos C, por lo que quien no pueda leerlo debería abandonar su trabajo más temprano que tarde. – Ingo

13

esto está bien. se llama final en blanco

cita de wiki:

Una variable definitiva sólo se puede inicializar una vez, ya sea a través de un inicializador o una instrucción de asignación. No es necesario inicializarlo en el punto de la declaración: esto se llama una variable "final en blanco". Una variable de instancia final en blanco de una clase debe asignarse definitivamente al final de cada constructor de la clase en la que se declara; de manera similar, una variable estática final en blanco debe asignarse definitivamente en un inicializador estático de la clase en la que se declara: ; de lo contrario, se produce un error de tiempo de compilación en ambos casos. [4] (Nota: Si la variable es una referencia, esto significa que la variable no puede ser re-obligado hacer referencia a otro objeto, pero el objeto de que referencias sigue siendo mutable, si era originalmente mutable..)

blanco final de

La pieza final, que se introdujo en Java 1.1, es una variable definitiva cuya declaración carece de un inicializador. [5] [6] Una final en blanco solo puede asignarse una vez y debe ser desasignada cuando ocurre una asignación.En para hacer esto, un compilador Java ejecuta un análisis de flujo para asegurar que, para cada asignación a una variable final en blanco, la variable es definitivamente sin asignar antes de la asignación; de lo contrario, se produce un error en tiempo de compilación. [7]

En general, un compilador de Java se asegurará de que el espacio en blanco final no es utilizarse hasta que se le asigna un valor y que una vez asignado un valor, la última variable de ahora no puede ser reasignado otro valor. [8]

enlace: http://en.wikipedia.org/wiki/Final_%28Java%29

+1

Guau, pensé que conocía toda la sintaxis de Java al menos, gracias por explicarme esta nueva arruga. – ArtB

1

Especificación del lenguaje Java contiene un capítulo entero dedicado a este comportamiento (Chapter 16 Definite Assignment).

Este comportamiento está completamente definido, por lo que creo que malinterpretas algo cuando dices que solía producir un error en versiones anteriores.

0

Sí, esto funcionará y es seguro de usar en todas las versiones de Java que he visto (1.3+).

final significa que no puede cambiar el valor del objeto una vez que se ha inicializado, si se colocó un valor nulo al declararse que se hubiera roto.

Cuestiones relacionadas