Confiar en la inicialización de campo predeterminada: ¿es un mal estilo de programación? [cerrado]

20

Me dieron un enlace a la documentación oficial de Oracle: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html

donde se dice:

Valores predeterminados

No siempre es necesario asignar un valor cuando se declara un campo. El compilador establecerá los campos declarados pero no inicializados en un valor predeterminado razonable. En términos generales, este valor predeterminado será cero o nulo, según el tipo de datos. Sin embargo, confiar en estos valores predeterminados generalmente se considera un mal estilo de programación.

Quiero enfatizar esta parte:

Sin embargo, confiar en estos valores predeterminados generalmente se considera un mal estilo de programación.

Pero, vaya, esto es, yo diría, una parte fundamental de la especificación del lenguaje sabiendo que las variables de instancia tienen valores predeterminados. ¿Por qué es una mala práctica de programación si se usa ampliamente incluso en el código fuente de las bibliotecas Java SE?

Andremoniy
fuente
55
Huh Nunca supe que esa declaración estaba allí. De hecho, considero una buena práctica confiar en ellos. private int count = 0;es un código que no hace nada, y el código que no hace nada es desorden. Es como importar clases de java.lang, o declarar una clase con extends Object.
VGR
2
... o tener un public abstractmétodo en una interfaz.
Mumpitz
1
¿Qué tiene de malo el resumen público?
John Keates
1
Una pieza del rompecabezas puede provenir de C ++. Es un lenguaje popular, y su manejo de inicialización predeterminada versus inicialización cero es una fuente continua de errores. En C ++, es una mala idea confiar en los valores predeterminados en todos los casos, excepto en los más excepcionales. Eso puede haberse filtrado a Java culturalmente.
Cort Ammon
@JohnKeates: mi Java está un poco oxidado, pero los privatemétodos en una interfaz no tendrían sentido, y abstractestá implícito.
Scott Smith

Respuestas:

6

El texto citado es:

"Sin embargo, confiar en esos valores predeterminados generalmente se considera un mal estilo de programación".

Cínicamente: "generalmente se considera que" es a menudo una forma de decir que el autor no ha tratado de encontrar una fuente autorizada para la declaración que se presenta.

En este caso, la afirmación es claramente cuestionable. Evidencia: 5 de las 5 Guías de estilo Java muestreadas NO dicen nada sobre si debería o debería confiar en los valores predeterminados:

(Tenga en cuenta que mi metodología para el muestreo fue mirar los primeros 5 resultados distintos de búsqueda de Google para "guía de estilo java". Luego busqué en cada documento el "valor predeterminado". Este no es un análisis exhaustivo, pero sirve para aclarar mi punto. )


OKAY. Entonces, ¿realmente ayuda a la legibilidad del código Java?

Esto es discutible.

Por un lado, un programador Java novato que no ha aprendido sobre la inicialización predeterminada puede estar desconcertado acerca de dónde provienen los ceros o los valores nulos. Pero si se molestan en buscar una inicialización explícita y encuentran que no hay una, eso debería ser suficiente para hacer que lean un tutorial o libro para averiguar sobre la inicialización predeterminada. (¡Lo esperarías!)

Por otro lado, normalmente no esperamos que los programadores Java novatos mantengan bases de código de producción. Para un programador Java experimentado, una inicialización redundante no mejora la legibilidad. Es (en el mejor de los casos) ruido.

En mi opinión, lo único que se logra mediante una inicialización redundante de un campo es indicar a un futuro lector de su código que ha pensado en el valor inicial. (Como lo expresó @GhostCat, la inicialización predeterminada no comunica la intención).

Pero, por el contrario, si fuera ese lector, no necesariamente confiaría en el pensamiento del autor del código. Entonces el valor de esta "señal" también es cuestionable.


¿Qué pasa con la fiabilidad?

En Java no hay diferencia. El JLS especifica que la inicialización por defecto no ocurre para los campos. Y a la inversa, para las variables locales es un error de compilación intentar usar una variable que no se ha inicializado definitivamente.

En resumen, el comportamiento en tiempo de ejecución de una variable que no se inicializa explícitamente es completamente predecible.

Por el contrario, en lenguajes como C o C ++, donde las variables pueden no inicializarse, el comportamiento no se especifica y puede provocar bloqueos y diferencias de comportamiento en diferentes plataformas. El caso de siempre inicializar explícitamente las variables es mucho más fuerte aquí.


¿Qué pasa con el rendimiento?

No debería hacer ninguna diferencia. El compilador JIT debería poder tratar una inicialización redundante y una inicialización predeterminada de la misma manera.

Stephen C
fuente
19

Simple: confiar en valores predeterminados no comunica intención.

¿Realmente quería que ese campo comenzara con 0, o se olvidó de asignar un valor?

Y, por supuesto, una referencia nula es la mitad de las dos cosas que necesita para encontrarse con una excepción de puntero nulo.

Finalmente, el uso de valores predeterminados implica que tiene campos no finales. Que evitas siempre que sea posible.

El único argumento contrario es: ¿por qué escribir cosas que no tiene que hacer? Pero creo que las desventajas enumeradas anuncian que, por lo tanto, asignar 0 a un campo explícitamente es mejor que dejarlo al compilador.

GhostCat saluda a Monica C.
fuente
3
es decir, re: no comunicar intención - ¿Qué sucede si "Manny el mantenedor" está mirando su código y no sabe cuál es el valor predeterminado para un tipo de datos específico? Está asumiendo que es 0 cuando es realmente NULL y ese es el error completo en una verificación === (o cualquiera que sea la verificación de igualdad equivalente para value & type está en java, igual ()?). Horas de búsqueda (para un programador inexperto) podrían ser el resultado de algo tan simple. PD tratando de jugar al abogado del diablo. Digo que use los valores predeterminados todo el día (aunque nunca lo hago) y obtenga personas más inteligentes (o al menos mayor atención al detalle) para mantener su código.
TCooper
@TCooper cuando mannie el mantenedor sabe muy poco sobre Java, entonces no tiene nada que ver con el código Java del mundo real. Pero estoy de acuerdo con la noción subyacente. Hace las cosas más difíciles para los novatos.
GhostCat saluda a Monica C. el
12

¿Por qué demonios es una mala práctica de programación?

La idea es que si confía en un valor predeterminado, no está claro de inmediato para cualquiera que lea el código si lo dejó deliberadamente como el valor predeterminado, o si simplemente olvidó asignarlo.

... si se usa ampliamente incluso en el código fuente de las bibliotecas Java SE?

El código fuente de Java no es realmente algo en lo que deba confiar como un ejemplo de práctica de codificación ejemplar. Hay muchos casos en los que se violan dichas reglas (a veces intencionalmente por mejoras menores de rendimiento, y a veces accidentalmente o porque el estilo aceptado ha cambiado con los años).

Michael Berry
fuente
2
Esto probablemente sea correcto, aunque no estoy de acuerdo con eso.
VGR
3
@VGR Aunque tiendo a estar de acuerdo con la afirmación de que confiar en los valores predeterminados es subóptimo, tuve cuidado de expresarlo de manera neutral por esa razón. La calidad del código es subjetiva, y soy consciente de que esta no es una visión universal.
Michael Berry