2010-11-04 22 views
12

En muchas piezas de código de ejemplo veo variables instaladas con valores nulos y más tarde se les asignan valores más significativos.Por qué crear instancias de variables con un valor nulo

Me preguntaba por qué las personas pueden hacer esto. Supongo que los bloques de prueba pueden entrar en esto, pero también veo que las variables instanciadas anularán los valores dentro de un bloque de prueba.

(Estoy seguro de que esta es una pregunta bastante agnóstico idioma, pero sólo para referencia programo casi en su totalidad en Java)

Todos los puntos de vista apreciados!

+3

Creo que es una pregunta válida. +1 para equilibrar el downvote. –

+0

Eso es lo que sucede cuando el infractor no deja un comentario. –

+0

Simplemente porque en muchos casos, de lo contrario, el código simplemente no se compilará. Ahora, ¿por qué las especificaciones de Java obligan a esta es otra pregunta, pero +1 a MForster, que señaló el mensaje de error del compilador exacto. Tenga en cuenta que ni siquiera necesita compilar un archivo * .java * válido para obtener este mensaje de error. Por ejemplo: IntelliJ IDEA (increíble IDE de Java) le advertirá acerca de su ** error ** en tiempo real, incluso en un AST parcial (es decir: un archivo .java parcial que no podría compilar usted mismo porque está incompleto) – SyntaxT3rr0r

Respuesta

13

El compilador de Java detecta en ciertos casos si una variable no se ha inicializado en todos los flujos de control posibles e imprime un error. Para evitar estos mensajes de error, es necesario inicializar explícitamente la variable.

Por ejemplo, en este caso:

public Integer foo() { 
    Integer result; 

    if (Math.random() < 0.5) { 
     result = 1; 
    } 

    return result; 
    } 

El compilador daría a este mensaje de error: "El resultado variable local no se haya inicializado".

Aquí es lo que el Java Language Specification dice:

Cada variable local (§14.4) y cada espacio en blanco final (§4.5.4) campo (§8.3.1.2) debe tener un valor asignado definitivamente cuando cualquier acceso de su valor ocurre. Un compilador Java debe llevar un análisis de flujo conservativo específico para asegurarse de que para cada acceso de una variable local o campo final en blanco f, f se asigna definitivamente antes del acceso; de lo contrario, debe producirse un error de tiempo de compilación .

Tenga en cuenta que (a diferencia de los campos!) Las variables locales no se inicializan automáticamente en null.

+0

¡Emite un error para ayudarlo a evitar excepciones de tiempo de ejecución! Yo no diría que es necesario. De hecho, diría que es muy pobre no asegurarse de que cada flujo de control tenga un objeto válido. – wheaties

+0

Me refería al mensaje de error del compilador. Creo que estos son incluso obligatorios según las especificaciones del lenguaje. – MForster

+12

¿Alguien más piensa que es extraño que QuakerOat haga esta pregunta, y Wheaties comentó una respuesta? –

4

Personalmente, no me gusta para los campos de miembros que tomarán un valor en el constructor. Hubo un momento en el que pensé que era agradable ser explícito, pero en realidad hay una diferencia de bytecode entre asignar un campo a nulo explícitamente o el campo que toma el valor predeterminado.

Incluso para los campos que empiezan como nulos (y luego ganan un valor en algún momento después de la inicialización) no soy un gran admirador de ellos. Por lo general, solo resalta la incomprensión del desarrollador que hizo eso.

La relevancia try-catch es en casos como este:

Reader r = null; 
try { 
    r = ...; 
    //do something that could throw an exception 
} finally { 
    if (r != null) { //wouldn't compile without assignment to null 
     r.close(); 
    } 
} 

Debido r es una variable local aquí se necesita un valor antes de que pueda ser utilizado, por lo que la asignación es necesaria. Si la asignación a null ocurre en la misma ruta de código que su posterior reasignación y/o uso, probablemente sea una redundancia engañosa.

+0

Normalmente, solo produzco código utilizando objetos inmutables, por lo que los campos de miembros que toman un valor en el constructor generalmente están todos marcados como * final * en mi código, lo que hace que el punto sea poco discutible: en ese caso simplemente no puede asignarlo * null * primero y luego cambiarlo en CTOR. – SyntaxT3rr0r

+0

@Webinator: Definitivamente. Un buen efecto secundario de los miembros finales. –

0

SÍ, pensé en esta pregunta muchas veces.

Por el momento, suelo dar un valor inicial null para un objeto y un valor sin sentido para el tipo simple. La razón, a veces no puedes estar seguro de que el JRE da valor inicial a la variable. Y a veces necesitas juzgar si la variable es nula, quizás te olvides de iniciarla.Algunos errores son fáciles de encontrar, si da a las variables un valor inicial.

Cuestiones relacionadas