Eu já vi exemplos como este:
public class MaxSeconds {
public static final int MAX_SECONDS = 25;
}
e supunha que eu poderia ter uma classe Constantes para agrupar constantes, declarando-as estáticas como finais. Conheço praticamente nenhum Java e estou me perguntando se essa é a melhor maneira de criar constantes.
Respostas:
Isso é perfeitamente aceitável, provavelmente até o padrão.
onde
TYPE
é o tipo,NAME
é o nome em todas as maiúsculas com sublinhado de espaços eVALUE
é o valor constante;Eu recomendo NÃO colocar suas constantes em suas próprias classes ou interfaces.
Como observação lateral: Variáveis declaradas finais e mutáveis ainda podem ser alteradas; no entanto, a variável nunca pode apontar para um objeto diferente.
Por exemplo:
Isso é legal e
ORIGIN
seria então um ponto em (3, 0).fonte
Eu recomendaria altamente não ter uma única classe de constantes. Pode parecer uma boa ideia no momento, mas quando os desenvolvedores se recusam a documentar constantes e a classe cresce para abranger mais de 500 constantes que nem todas são relacionadas umas às outras (sendo relacionadas a aspectos totalmente diferentes do aplicativo), geralmente se transforma no arquivo de constantes sendo completamente ilegível. Em vez de:
fonte
É uma PRÁTICA RUIM usar interfaces apenas para manter constantes (denominado padrão de interface constante por Josh Bloch). Aqui está o que Josh aconselha:
Exemplo:
Sobre a convenção de nomenclatura:
fonte
abstract
notação para a classe em vez do construtor privado.abstract
vez de um construtor privado não impede completamente a instanciação, porque é possível subclassificá-la e instanciar a subclasse (não que seja uma boa ideia fazê-lo, mas seja possível). @ToolmakerSteve Você não pode subclassificar uma classe com um construtor privado (pelo menos não sem um grande hack), porque o construtor da subclasse precisa chamar o construtor (agora privado) de sua superclasse. Portanto, marcá-lofinal
é desnecessário (mas talvez mais explícito).No Java efetivo (2ª edição), é recomendável usar enumerações em vez de entradas estáticas para constantes.
Há uma boa descrição sobre enumerações em Java aqui: http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html
Observe que, no final desse artigo, a pergunta é:
Com uma resposta de:
fonte
Apenas evite usar uma interface:
É tentador, mas viola o encapsulamento e desfoca a distinção das definições de classe.
fonte
Eu uso a seguinte abordagem:
Por exemplo, eu uso
Constants.DB.Connection.URL
para ficar constante. Parece mais "orientado a objetos" quanto a mim.fonte
Criar constantes finais estáticas em uma classe separada pode causar problemas. O compilador Java realmente otimiza isso e coloca o valor real da constante em qualquer classe que a referenciar.
Se você alterar posteriormente a classe 'Constants' e não fizer uma recompilação com outras classes que fazem referência a essa classe, você terminará com uma combinação de valores antigos e novos sendo usados.
Em vez de pensar nelas como constantes, pense nelas como parâmetros de configuração e crie uma classe para gerenciá-las. Tenha os valores não finais e considere o uso de getters. No futuro, como você determinar que alguns desses parâmetros realmente devem ser configuráveis pelo usuário ou administrador, será muito mais fácil.
fonte
O erro número um que você pode cometer é criar uma classe acessível globalmente chamada com um nome genérico, como Constantes. Isso simplesmente fica cheio de lixo e você perde toda a capacidade de descobrir qual parte do seu sistema usa essas constantes.
Em vez disso, as constantes devem entrar na classe que as "possui". Você tem uma constante chamada TIMEOUT? Provavelmente deve entrar na sua classe Communications () ou Connection (). MAX_BAD_LOGINS_PER_HOUR? Entra em Usuário (). E assim por diante.
O outro uso possível são os arquivos Java .properties quando "constantes" podem ser definidas em tempo de execução, mas não são facilmente alteráveis pelo usuário. Você pode empacotá-los em seus .jars e referenciá-los com o class resourceLoader.
fonte
Esse é o caminho certo a seguir.
Geralmente, as constantes não são mantidas em classes "Constantes" separadas porque não são detectáveis. Se a constante for relevante para a classe atual, mantê-los lá ajuda o próximo desenvolvedor.
fonte
Que tal uma enumeração?
fonte
Eu prefiro usar getters do que constantes. Esses getters podem retornar valores constantes, por exemplo
public int getMaxConnections() {return 10;}
, mas qualquer coisa que precise da constante passará por um getter.Um benefício é que, se o seu programa ultrapassar a constante - você achar que precisa ser configurável - você poderá alterar como o getter retorna a constante.
O outro benefício é que, para modificar a constante, você não precisa recompilar tudo o que a usa. Quando você faz referência a um campo final estático, o valor dessa constante é compilado em qualquer bytecode que a referencie.
fonte
Concordo que o uso de uma interface não é o caminho a percorrer. Evitar esse padrão ainda tem seu próprio item (# 18) no Java eficaz de Bloch .
Um argumento que Bloch faz contra o padrão de interface constante é que o uso de constantes é um detalhe de implementação, mas a implementação de uma interface para usá-los expõe esse detalhe de implementação em sua API exportada.
o
public|private static final TYPE NAME = VALUE;
padrão é uma boa maneira de declarar uma constante. Pessoalmente, acho que é melhor evitar fazer uma aula separada para abrigar todas as suas constantes, mas nunca vi uma razão para não fazer isso, além da preferência e estilo pessoais.Se suas constantes puderem ser bem modeladas como uma enumeração, considere o enum estrutura de disponível em 1.5 ou posterior.
Se você estiver usando uma versão anterior à 1.5, ainda poderá extrair enumerações de tipos seguros usando classes Java normais. (Veja este site para mais informações).
fonte
Com base nos comentários acima, acho que essa é uma boa abordagem para alterar a classe constante global à moda antiga (com variáveis finais estáticas públicas) para seu equivalente enum da seguinte maneira:
Então, eu posso indicá-los para gostar:
fonte
Um bom design orientado a objetos não deve precisar de muitas constantes publicamente disponíveis. A maioria das constantes deve ser encapsulada na classe que precisa delas para fazer seu trabalho.
fonte
Há uma certa quantidade de opinião para responder a isso. Para começar, as constantes em java geralmente são declaradas públicas, estáticas e finais. Abaixo estão os motivos:
Eu nunca usaria uma interface para um acessador / objeto CONSTANTS simplesmente porque geralmente é esperado que as interfaces sejam implementadas. Isso não seria engraçado:
Em vez disso, eu escolheria entre algumas maneiras diferentes, com base em algumas vantagens e desvantagens, e isso depende do que você precisa:
fonte
Uma abordagem que realmente devemos evitar : usar interfaces para definir constantes.
Criar uma interface especificamente para declarar constantes é realmente a pior coisa: derrota a razão pela qual as interfaces foram projetadas: definindo o (s) método (s) contratado (s).
Mesmo que já exista uma interface para atender a uma necessidade específica, declarar as constantes nelas não faz muito sentido, pois as constantes não devem fazer parte da API e do contrato fornecido às classes do cliente.
Para simplificar, temos amplamente quatro abordagens válidas .
Com
static final String/Integer
campo:Com
Java 5 enum
:TLDR: Qual é a melhor maneira e onde localizar as constantes?
Na maioria dos casos, a maneira enum é provavelmente melhor do que a
static final String/Integer
maneira e, pessoalmente, acho que astatic final String/Integer
maneira deve ser usada apenas se tivermos boas razões para não usar enum.E sobre onde devemos declarar os valores constantes, a idéia é pesquisar se existe uma única classe existente que possua uma coesão funcional específica e forte com valores constantes. Se encontrarmos essa classe, devemos usá-la como detentora de constantes . Caso contrário, a constante deve ser associada a nenhuma classe em particular.
static final String
/static final Integer
versusenum
O uso de enums é realmente uma maneira de considerar fortemente.
Enums têm uma grande vantagem sobre
String
ouInteger
campo constante.Eles estabelecem uma restrição de compilação mais forte. Se você definir um método que aceita a enum como parâmetro, poderá transmitir apenas um valor de enum definido na classe de enum (ou nula).
Com String e Inteiro, você pode substituí-los por quaisquer valores do tipo compatível e a compilação será boa, mesmo que o valor não seja uma constante definida nos campos
static final String
/static final Integer
.Por exemplo, abaixo de duas constantes definidas em uma classe como
static final String
campos:Aqui, um método que espera ter uma dessas constantes como parâmetro:
Você pode invocá-lo desta maneira:
ou
Mas nenhuma restrição de compilação impede que você a invoque desta maneira:
Você teria o erro apenas no tempo de execução e somente se fizer uma verificação de cada vez do valor transmitido.
Com enum, as verificações não são necessárias, pois o cliente pode transmitir apenas um valor de enum em um parâmetro enum.
Por exemplo, aqui dois valores definidos em uma classe enum (tão constante fora da caixa):
Aqui, um método que espera ter um desses valores de enumeração como parâmetro:
Você pode invocá-lo desta maneira:
ou
Mas a compilação nunca permitirá que você a invoque desta maneira:
Onde devemos declarar as constantes?
Se seu aplicativo contiver uma única classe existente que possua uma coesão funcional específica e forte com os valores constantes, o 1) e o 2) parecerão mais intuitivos.
Geralmente, facilita o uso das constantes se elas forem declaradas na classe principal que as manipula ou que tiverem um nome muito natural para adivinhar que a encontraremos lá dentro.
Por exemplo, na biblioteca JDK, os valores exponenciais e constantes pi são declarados em uma classe que declara não apenas declarações constantes (
java.lang.Math
).Os clientes que usam funções matemáticas dependem frequentemente da
Math
classe. Portanto, eles podem encontrar constantes com bastante facilidade e também podem se lembrar de ondeE
ePI
são definidos de uma maneira muito natural.Se seu aplicativo não contiver uma classe existente que tenha uma coesão funcional muito específica e forte com os valores constantes, as formas 1 e 2) parecerão mais intuitivas.
Geralmente, não facilita o uso das constantes se elas são declaradas em uma classe que as manipula, enquanto também temos 3 ou 4 outras classes que as manipulam tanto quanto e nenhuma dessas classes parece ser mais natural do que outras. hospedar valores constantes.
Aqui, definir uma classe personalizada para manter apenas valores constantes faz sentido.
Por exemplo, na biblioteca JDK, o
java.util.concurrent.TimeUnit
enum não é declarado em uma classe específica, pois não existe realmente uma e apenas uma classe específica do JDK que aparece como a mais intuitiva para mantê-la:Muitas classes declarou em
java.util.concurrent
usá-los:BlockingQueue
,ArrayBlockingQueue<E>
,CompletableFuture
,ExecutorService
, ... e realmente nenhum deles parece mais adequado para segurar o enum.fonte
Uma constante, de qualquer tipo, pode ser declarada criando uma propriedade imutável que dentro de uma classe (que é uma variável de membro com o
final
modificador). Normalmente, os modificadoresstatic
epublic
também são fornecidos.Existem inúmeras aplicações em que o valor de uma constante indica uma seleção de uma n-tupla (por exemplo, enumeração ) de opções. Em nosso exemplo, podemos escolher definir um tipo enumerado que restringirá os possíveis valores atribuídos (ou seja , segurança de tipo aprimorada ):
fonte
Uma única classe de constantes genéricas é uma má ideia. As constantes devem ser agrupadas com a classe com a qual estão mais logicamente relacionadas.
Em vez de usar variáveis de qualquer tipo (especialmente enumerações), sugiro que você use métodos. Crie um método com o mesmo nome que a variável e faça com que ele retorne o valor que você atribuiu à variável. Agora exclua a variável e substitua todas as referências a ela por chamadas para o método que você acabou de criar. Se você acha que a constante é genérica o suficiente para não precisar criar uma instância da classe apenas para usá-la, faça do método constant um método de classe.
fonte
FWIW, um valor de tempo limite em segundos provavelmente deve ser uma configuração (lida em um arquivo de propriedades ou por injeção como no Spring) e não uma constante.
fonte
Qual é a diferença
1
2)
e usando
MyGlobalConstants.TIMEOUT_IN_SECS
sempre que precisarmos dessa constante. Eu acho que ambos são iguais.fonte
Eu não chamaria a classe da mesma (além de maiúsculas e minúsculas) da constante ... Eu teria no mínimo uma classe de "Configurações", "Valores" ou "Constantes", onde todas as constantes viveriam. Se eu tiver um grande número deles, os agruparia em classes constantes lógicas (UserSettings, AppSettings, etc.)
fonte
Para dar um passo adiante, você pode colocar constantes usadas globalmente em uma interface para que elas possam ser usadas em todo o sistema. Por exemplo
Mas não o implemente. Basta consultá-los diretamente no código através do nome completo da classe.
fonte
Para constantes, o Enum é uma escolha melhor IMHO. Aqui está um exemplo
classe pública myClass {
fonte
Uma das maneiras que faço é criar uma classe 'Global' com os valores constantes e fazer uma importação estática nas classes que precisam acessar a constante.
fonte
static final
é minha preferência, eu só usaria umenum
se o item fosse realmente enumerável.fonte
Eu uso
static final
para declarar constantes e ir com a notação de nomeação ALL_CAPS. Eu já vi algumas instâncias da vida real em que todas as constantes são agrupadas em uma interface. Algumas postagens justificaram isso como uma má prática, principalmente porque não é para isso que serve uma interface. Uma interface deve impor um contrato e não deve ser um local para colocar constantes não relacionadas. Reuni-lo em uma classe que não pode ser instanciada (por meio de um construtor privado) também é bom se a semântica constante não pertencer a uma classe específica ( es). Eu sempre coloco uma constante na classe com a qual ela está mais relacionada, porque isso faz sentido e também é fácil de manter.As enums são uma boa opção para representar uma faixa de valores, mas se você estiver armazenando constantes independentes com ênfase no valor absoluto (por exemplo, TIMEOUT = 100 ms), basta seguir a
static final
abordagem.fonte
Concordo com o que a maioria está dizendo, é melhor usar enumerações ao lidar com uma coleção de constantes. No entanto, se você estiver programando no Android, há uma solução melhor: Anotação IntDef .
A anotação IntDef é superior às enumerações de uma maneira simples, ocupa muito menos espaço, pois é simplesmente um marcador de tempo de compilação. Não é uma classe, nem possui a propriedade de conversão automática de cadeias.
fonte
É um péssimo hábito e uma prática terrivelmente irritante citar Joshua Bloch sem entender o fundamentalismo básico do ponto zero.
Eu não li nada Joshua Bloch, então também
Como no fundamentalismo bíblico, todas as leis bíblicas podem ser resumidas por
e, de modo semelhante, o fundamentalismo da engenharia de software pode ser resumido em
Além disso, entre os círculos fundamentalistas bíblicos, um corolário forte e razoável é traçado
Da mesma forma, se você não se respeita como programador e apenas aceita os pronunciamentos e profecias de algum guru-nath da programação SEM questionar os fundamentos, suas citações e confiança em Joshua Bloch (e similares) não fazem sentido. E, portanto, você realmente não respeitaria seus colegas programadores.
As leis fundamentais da programação de software
As constantes do padrão de interface são um mau hábito ???
Sob quais leis da programação fundamentalmente eficaz e responsável se enquadra esse edito religioso?
Basta ler o artigo da wikipedia sobre constantes de padrão de interface ( https://en.wikipedia.org/wiki/Constant_interface ), e as desculpas tolas que ele declara em relação às constantes de padrão de interface.
Whatif-No IDE? Quem diabos, como programador de software, não usaria um IDE? Muitos de nós somos programadores que preferem não ter que provar ter um sobrevivencialismo escapular masculino, evitando o uso de um IDE.
Polui o espaço para nome com variáveis não usadas no escopo atual? Poderia ser proponente dessa opinião
O uso de interfaces para impor constantes é um abuso de interfaces. Os proponentes de tais têm um mau hábito de
É difícil, senão impossível, converter interfaces em classes implementadas no futuro. Hah .... hmmm ... ???
Quaisquer que sejam as desculpas, NÃO EXISTEM VÁLIDAS VÁLIDAS no que diz respeito à engenharia de software FUNDAMENTALMENTE EFICAZ para deslegitimar ou geralmente desencorajar o uso de constantes de interface.
Não importa quais foram as intenções e estados mentais originais dos pais fundadores que criaram a Constituição dos Estados Unidos. Poderíamos debater as intenções originais dos pais fundadores, mas tudo o que me interessa são as declarações escritas da Constituição dos EUA. E é responsabilidade de todo cidadão dos EUA explorar o fundamentalismo literário escrito, não os fundamentos não escritos da Constituição dos EUA.
Da mesma forma, não me importo com o que as intenções "originais" dos fundadores da plataforma Java e da linguagem de programação tinham para a interface. O que importa são os recursos efetivos que a especificação Java fornece e pretendo explorar esses recursos ao máximo para me ajudar a cumprir as leis fundamentais da programação de software responsável. Não me importo se sou percebido como "violando a intenção de interfaces". Não me importo com o que Gosling ou alguém Bloch diz sobre a "maneira correta de usar Java", a menos que o que eles digam não viole minha necessidade de cumprir com EFICAZ os fundamentos.
O fundamental é a normalização do modelo de dados
Não importa como seu modelo de dados é hospedado ou transmitido. Se você usa interfaces ou enumerações ou qualquer que seja, relacional ou não-SQL, se não entender a necessidade e o processo de normalização do modelo de dados.
Primeiro, devemos definir e normalizar o modelo de dados de um conjunto de processos. E quando temos um modelo de dados coerente, SOMENTE então podemos usar o fluxo do processo de seus componentes para definir o comportamento funcional e o processo bloqueia um campo ou domínio de aplicativos. E somente então podemos definir a API de cada processo funcional.
Mesmo as facetas da normalização de dados, conforme proposto pelo EF Codd, agora são severamente desafiadas e severamente desafiadas. por exemplo, sua declaração sobre a 1NF foi criticada por ser ambígua, desalinhada e simplificada demais, assim como o restante de suas declarações, especialmente no advento dos modernos serviços de dados, re-tecnologia e transmissão. Na IMO, as instruções EF Codd devem ser completamente descartadas e um novo conjunto de instruções matematicamente plausíveis deve ser projetado.
Uma falha evidente dos EF Codd e a causa de seu desalinhamento da compreensão humana eficaz é sua crença de que dados multidimensionais e de dimensões mutáveis humanamente perceptíveis podem ser eficientemente percebidos através de um conjunto de mapeamentos bidimensionais fragmentados.
Os fundamentos da normalização de dados
O que a EF Codd não conseguiu expressar.
Dentro de cada modelo de dados coerente, estas são a ordem graduada sequencial de coerência do modelo de dados a ser atingida.
Em um campo ou grade de aplicativos de componentes entre serviços, deve haver um e apenas um modelo de dados coerente ou existe um meio para um modelo / versão de dados se identificar.
Ainda estamos perguntando se poderíamos usar constantes de interface? Realmente ?
Há questões de normalização de dados em jogo mais conseqüentes do que essa questão mundana. Se você não resolver esses problemas, a confusão que você acha que as constantes da interface causam é comparativamente nada. Zilch.
A partir da normalização do modelo de dados, você determina os componentes como variáveis, como propriedades, como constantes da interface do contrato.
Em seguida, você determina o que entra em injeção de valor, espaço reservado na configuração da propriedade, interfaces, cadeias finais, etc.
Se você precisar usar a desculpa de precisar localizar um componente mais fácil de determinar em relação às constantes da interface, isso significa que você tem o mau hábito de não praticar a normalização do modelo de dados.
Talvez você queira compilar o modelo de dados em um release do vcs. Que você pode obter uma versão distintamente identificável de um modelo de dados.
Os valores definidos nas interfaces são completamente garantidos como não mutáveis. E compartilhável. Por que carregar um conjunto de seqüências finais em sua classe a partir de outra classe quando tudo que você precisa é esse conjunto de constantes?
Então, por que não publicar um contrato de modelo de dados? Quero dizer, se você pode gerenciar e normalizá-lo de forma coerente, por que não? ...
Agora posso referenciar os rótulos contratados dos meus aplicativos de uma maneira como
Isso confunde o conteúdo do arquivo jar? Como programador Java, não me importo com a estrutura do jar.
Isso apresenta complexidade à troca de tempo de execução motivada por osgi? Osgi é um meio extremamente eficiente para permitir que os programadores continuem com seus maus hábitos. Existem alternativas melhores que osgi.
Ou por que não isso? Não há vazamento das constantes privadas no contrato publicado. Todas as constantes privadas devem ser agrupadas em uma interface privada chamada "Constantes", porque não quero procurar constantes e tenho preguiça de digitar repetidamente "private final String".
Talvez até isso:
O único problema com as constantes da interface que vale a pena considerar é quando a interface é implementada.
Esta não é a "intenção original" das interfaces? Como se eu me importasse com a "intenção original" dos pais fundadores na elaboração da Constituição dos EUA, e não como a Suprema Corte interpretaria as cartas escritas da Constituição dos EUA ???
Afinal, moro na terra dos livres, da natureza e do lar dos bravos. Seja corajoso, livre, seja selvagem - use a interface. Se meus colegas programadores se recusarem a usar meios de programação eficientes e preguiçosos, sou obrigado pela regra de ouro a diminuir minha eficiência de programação para se alinhar à deles? Talvez eu deva, mas essa não é uma situação ideal.
fonte