Convenção de nomenclatura: Campos finais (não estáticos)

23

Hoje tive uma discussão com um colega de trabalho sobre a nomeação de finalcampos nas classes Java.

Em sua opinião, os finalcampos também devem ser considerados constantes, pois seus valores não serão alterados após a criação da instância.

Isso levaria à seguinte convenção de nomenclatura para finalcampos:

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

    private final String BAR_BATZ;

    ...
}

Na minha opinião, apenas os static finalcampos devem ser considerados constantes, enquanto os campos que são apenas finaldevem seguir a convenção de nomenclatura camelCase usual.

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

    private final String barBatz;

    ...
}

Agora estou um pouco inseguro, já que ele é um programador muito mais experiente do que eu e geralmente concordo com as opiniões dele e o considero um desenvolvedor muito bom.

Alguma contribuição sobre isso?

Sascha Wolf
fonte
Seus exemplos não são constantes; você não atribuiu nenhum valor a eles no momento da compilação. Portanto, eles não seguem as convenções de nomenclatura para constantes.
Robert Harvey
@RobertHarvey Obrigado, você está certo. O ...objetivo era simbolizar qualquer construtor possível que define o finalcampo, mas obviamente isso não é possível para o static finalcampo.
perfil completo de Sascha Wolf
1
@ Zeeker, você pode estar interessado nos static { }blocos que podem ser usados ​​para definir campos estáticos dentro de uma classe uma vez quando a classe é carregada. Trabalho relacionado com o construtor estático em Java .
@RobertHarvey Estou familiarizado com isso. Mas obrigado mesmo assim.
Sascha Lobo
1
Eu diria que, como a variável pertence a uma instância, ela será diferente de instância para instância, portanto não se aplica como uma constante. Eu usaria estojo de camelo.
Florian F

Respostas:

20

A Sun (e agora Oracle) manteve um documento intitulado Convenções de Código para a Linguagem de Programação Java . A última atualização foi em 99, mas a essência da linha de guia de estilo continua viva.

O capítulo 9 aborda convenções de nomenclatura.

Para um tipo de identificador de 'constantes':

Os nomes das variáveis ​​declaradas constantes de classe e de ANSI devem estar em maiúsculas com palavras separadas por sublinhados ("_"). (As constantes ANSI devem ser evitadas, para facilitar a depuração.)

Os exemplos dados:

static final int MIN_WIDTH = 4;

static final int MAX_WIDTH = 999;

static final int GET_THE_CPU = 1;

Em um documento mais recente - ele entrou lá. Das variáveis ​​(Os tutoriais de Java> Aprendendo a linguagem Java> Noções básicas de linguagem :

Se o nome escolhido consistir em apenas uma palavra, soletre essa palavra em todas as letras minúsculas. Se consistir em mais de uma palavra, coloque em maiúscula a primeira letra de cada palavra subsequente. Os nomes gearRatioe currentGearsão exemplos principais desta convenção. Se sua variável armazena um valor constante, como, por exemplo static final int NUM_GEARS = 6, a convenção muda um pouco, capitalizando cada letra e separando as palavras subsequentes com o caractere sublinhado. Por convenção, o caractere sublinhado nunca é usado em outro lugar.

Muitos analisadores estáticos para Java procuram aplicar isso. Por exemplo, o estilo de verificação impõe:

Verifica se os nomes constantes estão em conformidade com um formato especificado pela propriedade format. Uma constante é um campo estático e final ou um campo de interface / anotação, exceto serialVersionUIDe serialPersistentFields. O formato é uma expressão regular e o padrão é ^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$.


Isso realmente se resume às convenções da comunidade escrevendo o código ... e, idealmente, mantendo o mesmo.

Os exemplos acima são dados como static finalaqueles que provavelmente são derivados das convenções C para #define- que, como C, são substituídos no código durante a compilação e não no tempo de execução.

A pergunta que então deve ser feita é "isso está se comportando como uma constante? Ou está se comportando como um campo de gravação única?" - e depois seguindo as convenções em conformidade. O teste decisivo para essa pergunta seria "Se você fosse serializar o objeto, incluiria o campo final?" Se a resposta for uma constante, trate-a como tal (e não a serialize). Por outro lado, se for parte do estado do objeto que precisaria ser serializado, não será uma constante.

Seja qual for o caso, é importante manter o estilo do código, por mais certo ou errado que seja. Problemas piores surgem de convenções inconsistentes em um projeto do que apenas algo que ofende os olhos. Considere obter algumas ferramentas de análise estática e configurá-las para manter a consistência.


fonte
@RobertHarvey Eu poderia conceber algumas situações em que um campo de instância está se comportando como uma constante. Uma fábrica, por exemplo, preenchendo algo que, de outra forma, seria uma constante no objeto ... embora estes cheguem a exemplos bastante artificiais que machucam minha cabeça só de pensar por que alguém faria isso.
Obrigado por esta resposta detalhada. O teste decisivo sobre a serialização do objeto fez o acordo para mim.
Sascha Wolf
Um colega fez questão de dizer recentemente que, uma vez, os editores não eram muito bons em destacar estáticas / estáticas, etc., portanto, essa convenção de nomes era importante. Hoje em dia, os IDEs são muito bons, então talvez possamos criar nomes mais agradáveis ​​para eles, por exemplo: em MinWidthvez de MIN_WIDTH. Outra pergunta é: e os registradores finais estáticos? Você liga para eles LOG/ LOGGERou log/ logger. Pessoalmente, logparece melhor alinhado com o código, mas quando é inconsistente aceitável?
Ndtreviv 21/06
5

BAR_BATZnão é uma constante neste exemplo. Os construtores de Foopodem configurá-lo para diferentes valores no nível do objeto. Por exemplo

public class Foo {
    private final String BAR_BATZ;

    Foo() {
       BAR_BATZ = "ascending";
    } 

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