Suponha que você precise definir uma classe em que tudo o que ela faz é manter constantes.
public static final String SOME_CONST = "SOME_VALUE";
Qual é a forma preferida de fazer isso?
- Interface
- Classe Abstrata
- Aula Final
Qual devo usar e por quê?
Esclarecimentos para algumas respostas:
Enums - não vou usar enums, não estou enumerando nada, apenas coletando algumas constantes que não estão relacionadas entre si de forma alguma.
Interface - não vou definir nenhuma classe como aquela que implementa a interface. Só quer usar a interface para chamar constantes assim: ISomeInterface.SOME_CONST
.
java
class-constants
Yuval Adam
fonte
fonte
Respostas:
Use uma aula final. para simplificar, você pode usar uma importação estática para reutilizar seus valores em outra classe
public final class MyValues { public static final String VALUE1 = "foo"; public static final String VALUE2 = "bar"; }
em outra classe:
import static MyValues.* //... if(variable.equals(VALUE1)){ //... }
fonte
VALUE1.equals(variable)
porque evita NPE.Seu esclarecimento afirma: "Não vou usar enums, não estou enumerando nada, apenas coletando algumas constantes que não estão relacionadas entre si de forma alguma."
Se as constantes não estão relacionadas entre si, por que você deseja agrupá-las? Coloque cada constante na classe com a qual está mais intimamente relacionada.
fonte
Minhas sugestões (em ordem decrescente de preferência):
1) Não faça isso . Crie as constantes na classe real onde são mais relevantes. Ter uma classe / interface de 'conjunto de constantes' não segue as melhores práticas OO.
Eu, e todos os outros, ignoramos o nº 1 de vez em quando. Se você vai fazer isso:
2) classe final com construtor privado Isso irá pelo menos evitar que alguém abuse do seu 'saco de constantes' estendendo / implementando-o para obter fácil acesso às constantes. (Eu sei que você disse que não faria isso - mas isso não significa que alguém virá depois de você)
3) interface Isso funcionará, mas não é minha preferência dar a possível menção de abuso no item 2.
Em geral, só porque essas são constantes, não significa que você não deva aplicar os princípios normais de oo a elas. Se apenas uma classe se preocupa com uma constante - deve ser particular e pertencer àquela classe. Se apenas os testes se importam com uma constante - ela deve estar em uma classe de teste, não em código de produção. Se uma constante for definida em vários lugares (não apenas acidentalmente a mesma) - refatorar para eliminar a duplicação. E assim por diante - trate-os como se fosse um método.
fonte
Como Joshua Bloch observa em Effective Java:
Você pode usar um Enum se todas as suas constantes estiverem relacionadas (como nomes de planetas), colocar os valores constantes nas classes às quais eles estão relacionados (se você tiver acesso a eles) ou usar uma classe de utilitário não instável (definir um construtor padrão privado) .
class SomeConstants { // Prevents instanciation of myself and my subclasses private SomeConstants() {} public final static String TOTO = "toto"; public final static Integer TEN = 10; //... }
Então, como já foi dito, você pode usar importações estáticas para usar suas constantes.
fonte
Meu método preferido é não fazer nada disso. A era das constantes praticamente morreu quando o Java 5 introduziu enums typesafe. E mesmo antes disso, Josh Bloch publicou uma versão (um pouco mais prolixa) disso, que funcionava no Java 1.4 (e anteriores).
A menos que você precise de interoperabilidade com algum código legado, não há mais razão para usar constantes String / inteiras nomeadas.
fonte
Basta usar a aula final.
Se você quiser adicionar outros valores, use uma classe abstrata.
Não faz muito sentido usar uma interface, uma interface deve especificar um contrato. Você só deseja declarar alguns valores constantes.
fonte
Enums não são a melhor escolha para esse tipo de coisa?
fonte
enum
s estão bem. IIRC, um item em Java eficaz (2ª Ed) temenum
constantes enumerando opções padrão que implementam uma [palavra-chave Java]interface
para qualquer valor.Minha preferência é usar uma [palavra
interface
- chave Java] em vezfinal class
de constantes for. Você obtém implicitamente opublic static final
. Algumas pessoas argumentarão que uminterface
permite que programadores ruins o implementem, mas programadores ruins irão escrever um código péssimo, não importa o que você faça.Qual parece melhor?
public final class SomeStuff { private SomeStuff() { throw new Error(); } public static final String SOME_CONST = "Some value or another, I don't know."; }
Ou:
public interface SomeStuff { String SOME_CONST = "Some value or another, I don't know."; }
fonte
Ou 4. Coloque-os na classe que contém a lógica que mais usa as constantes
... desculpe, não pude resistir ;-)
fonte
Uma das desvantagens do construtor privado é que o método nunca poderia ser testado.
Enum pelo conceito de natureza bom para aplicar em tipo de domínio específico, aplicá-lo a constantes descentralizadas parece não bom o suficiente
O conceito de Enum é "Enumerações são conjuntos de itens intimamente relacionados".
Estender / implementar uma interface constante é uma prática ruim, é difícil pensar sobre a necessidade de estender uma constante imutável em vez de se referir a ela diretamente.
Se aplicarmos uma ferramenta de qualidade como SonarSource, existem regras que obrigam o desenvolvedor a abandonar a interface constante, isso é uma coisa estranha, pois muitos projetos apreciam a interface constante e raramente as coisas "estendidas" acontecem em interfaces constantes
fonte