Convención de nomenclatura: campos finales (no estáticos)

23

Hoy tuve una discusión con un compañero de trabajo sobre el nombre de los finalcampos en las clases de Java.

En su opinión, los finalcampos también deben considerarse constantes, ya que sus valores no cambiarán después de la creación de la instancia.

Esto llevaría a la siguiente convención de nomenclatura para finalcampos:

public class Foo {
    private static final String BLA_BLA = "bla";

    private final String BAR_BATZ;

    ...
}

En mi opinión, solo los static finalcampos deben considerarse constantes, mientras que los campos que solo finaldeben seguir la convención de nomenclatura habitual de camelCase.

public class Foo {
    private static final String BLA = "bla";

    private final String barBatz;

    ...
}

Ahora estoy un poco inseguro ya que es un programador mucho más experimentado que yo y, por lo general, estoy de acuerdo con sus opiniones y lo considero un muy buen desarrollador.

¿Alguna aportación sobre esto?

Sascha Wolf
fuente
Tus ejemplos no son constantes; no les ha asignado ningún valor en tiempo de compilación. Ergo, no siguen las convenciones de nombres para constantes.
Robert Harvey
@RobertHarvey Gracias, tienes razón. El ...objetivo era simbolizar cualquier posible constructor que establezca el finalcampo, pero obviamente eso no es posible para el static finalcampo.
Sascha Wolf
1
@Zeeker puede interesarle los static { }bloques que se pueden usar para establecer campos estáticos dentro de una clase una vez que se carga la clase. Trabajo relacionado con el constructor estático en Java .
@RobertHarvey Estoy familiarizado con esos. Pero gracias de todos modos.
Sascha Wolf
1
Diría que dado que la variable pertenece a una instancia, será diferente de una instancia a otra, por lo que no se aplica como una constante. Yo usaría el caso de camello.
Florian F

Respuestas:

20

Sun (y ahora Oracle) mantuvo un documento titulado Convenciones de código para el lenguaje de programación Java . La última actualización de esto fue en el '99, pero la esencia de la línea de guía de estilo sigue viva.

El capítulo 9 cubre las convenciones de nomenclatura.

Para un tipo de identificador de 'constantes':

Los nombres de las variables declaradas constantes de clase y de las constantes ANSI deben estar en mayúsculas con palabras separadas por guiones bajos ("_"). (Deben evitarse las constantes ANSI para facilitar la depuración).

Los ejemplos dados:

static final int MIN_WIDTH = 4;

static final int MAX_WIDTH = 999;

static final int GET_THE_CPU = 1;

En un documento más reciente, se deslizó allí. De Variables (Los Tutoriales de Java> Aprendizaje del lenguaje Java> Conceptos básicos del lenguaje :

Si el nombre que elige consta de una sola palabra, deletree esa palabra en minúsculas. Si consta de más de una palabra, escriba en mayúscula la primera letra de cada palabra subsiguiente. Los nombres gearRatioy currentGearson ejemplos principales de esta convención. Si su variable almacena un valor constante, como static final int NUM_GEARS = 6, la convención cambia levemente, capitaliza cada letra y separa las palabras posteriores con el carácter de subrayado. Por convención, el carácter de subrayado nunca se usa en otra parte.

Muchos analizadores estáticos para Java buscan hacer cumplir esto. Por ejemplo, el estilo de control impone:

Comprueba que los nombres constantes se ajustan a un formato especificado por la propiedad de formato. Una constante es un campo estático y final o un campo de interfaz / anotación, excepto serialVersionUIDy serialPersistentFields. El formato es una expresión regular y su valor predeterminado es ^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$.


Esto realmente se reduce a las convenciones de la comunidad que escribe el código ... e idealmente lo mantiene igual.

Los ejemplos anteriores se dan como static finallos que probablemente se derivan de las convenciones de #defineC, que, como C, se reemplazan en el código durante la compilación en lugar de en tiempo de ejecución.

La pregunta que debería hacerse es "¿se comporta esto como una constante? ¿O se comporta como un campo de escritura única?" - y luego siguiendo las convenciones en consecuencia. La prueba de fuego para tal pregunta sería "Si tuviera que serializar el objeto, ¿incluiría el campo final?" Si la respuesta es que es una constante, trátela como tal (y no la serialice). Por otro lado, si es parte del estado del objeto que necesitaría ser serializado, entonces no es una constante.

Cualquiera sea el caso, es importante seguir con el estilo del código, por más que sea correcto o incorrecto. Los peores problemas surgen de convenciones inconsistentes dentro de un proyecto que simplemente algo que ofende la vista. Considere obtener algunas herramientas de análisis estático y configúrelas para mantener la coherencia.


fuente
@RobertHarvey Podría concebir algunas situaciones en las que un campo de instancia se comporta como una constante. Una Fábrica, por ejemplo, poblando algo que de otra forma sería una constante en el objeto ... aunque estos llegan a ejemplos bastante artificiales que me duelen la cabeza solo de pensar por qué uno lo haría.
Gracias por esta respuesta detallada. La prueba de fuego sobre la serialización del objeto hizo el trato por mí.
Sascha Wolf
Un colega hizo el punto válido recientemente al decir que, una vez, los editores no eran muy buenos para destacar finales estáticos / estáticos, etc., por lo que esta convención de nomenclatura era importante. En la actualidad, los IDE son bastante buenos, por lo que tal vez podamos crear nombres más bonitos para ellos, por ejemplo: en MinWidthlugar de MIN_WIDTH. Otra pregunta es: ¿qué pasa con los registradores finales estáticos? ¿Los llamas LOG/ LOGGERo log/ logger? Personalmente, se logve mejor en línea con el código, pero ¿cuándo es aceptable la inconsistencia?
ndtreviv
5

BAR_BATZNo es una constante en este ejemplo. Los constructores de Foopueden establecerlo en diferentes valores a nivel de objeto. Por ejemplo

public class Foo {
    private final String BAR_BATZ;

    Foo() {
       BAR_BATZ = "ascending";
    } 

    Foo(String barBatz) {
       BAR_BATZ = barBatz;
    }
}
Kirby
fuente