Eu estava passando por essa pergunta Existe uma maneira de substituir variáveis de classe em Java? O primeiro comentário com 36 votos positivos foi:
Se você vir um
protected static
, corra.
Alguém pode explicar por que é protected static
desaprovado?
final
. Um campo estático mutável compartilhado entre classes é definitivamente motivo de preocupação. É provável que várias classes que atualizam um campo estático não sejam confiáveis ou fáceis de seguir, especialmente porque a presença de qualquer campo ou método protegido implica que a classe deve ser estendida por classes em outros pacotes, possivelmente classes que não estão sob o controle do autor da classe que contém o campo protegido.final
não significa que o campo é imutável. Você sempre pode modificar oobject
referenciado por umafinal
variável de referência.Respostas:
É mais uma coisa estilística do que um problema direto. Isso sugere que você não pensou adequadamente no que está acontecendo com a classe.
Pense no que
static
significa:Pense no que
protected
significa:Os dois significados não são exatamente mutuamente exclusivos, mas são bem próximos.
O único caso em que posso ver onde você pode usar os dois juntos é se você tivesse uma classe abstrata que foi projetada para ser estendida e a classe estendida pudesse modificar o comportamento usando constantes definidas no original. Esse tipo de arranjo provavelmente acabaria muito confuso e indica fraqueza no design das classes.
Na maioria dos casos, seria melhor ter as constantes como públicas, pois isso apenas torna tudo mais limpo e permite que as pessoas subclasses tenham mais flexibilidade. Independentemente de qualquer outra coisa, em muitos casos, a composição é preferível à herança, enquanto as classes abstratas forçam a herança.
Para ver um exemplo de como isso pode quebrar as coisas e ilustrar o que quero dizer com a variável que não possui existência independente, tente este código de exemplo:
Você verá os resultados:
Experimente você mesmo em: https://ideone.com/KM8u8O
A classe
Test2
é capaz de acessar o membro estáticotest
partirTest
sem a necessidade de qualificar o nome - mas não herda ou obter sua própria cópia. Ele está olhando exatamente para o mesmo objeto na memória.fonte
Rectangle
) para ajustar a largura / altura para garantir que a igualdadeSquare
produzirá resultados indesejados se você substituir todos os supertipos por uma instância de seu subtipo.É desaprovado porque é contraditório.
Criar uma variável
protected
implica que ela será usada dentro do pacote ou será herdada dentro de uma subclasse .Tornar a variável o
static
torna um membro da classe, eliminando as intenções de herdá-la . Isso deixa apenas a intenção de ser usado dentro de um pacote , e temospackage-private
para isso (nenhum modificador).A única situação para a qual eu poderia achar útil é se você estivesse declarando uma classe que deveria ser usada para iniciar o aplicativo (como o JavaFX
Application#launch
e apenas queria poder iniciar a partir de uma subclasse. Se fizer isso, garanta que o método tambémfinal
seja disallow esconder . Mas este não é "a norma", e provavelmente foi implementada para evitar a adição de mais complexidade adicionando uma nova maneira de iniciar aplicativos.Para ver os níveis de acesso de cada modificador, consulte: Os tutoriais em Java - controlando o acesso aos membros de uma classe
fonte
static
eliminaria as intenções de herdá-lo. Porque minha subclasse em outro pacote ainda exige que o campo super sejaprotected
acessado, mesmo que sejastatic
.package-private
não pode ajudarprotected static
. Mas é um cheiro de código, daí a parte " executar ". Modificadores de acesso e herança são dois assuntos diferentes. Sim, você não poderá acessar um membro estático de uma superclasse, se fossepackage-private
. Mas você não deve confiar na herança para referenciar osstatic
campos em primeiro lugar; é um sinal de mau design. Você notará que tentativas de substituirstatic
métodos não dão resultados, o que é um sinal claro de que a herança não é baseada em classe. Se você precisar de fora o acesso da classe ou pacote, ele deve serpublic
private static
funções util no início, mas acho que alguém pode querer melhorar ou personalizar da minha classe e essas funções util também podem fornecer comodidade para elas.public
pode não ser apropriado, pois os métodos util não são para o usuário das instâncias da minha classe. Você poderia me ajudar a descobrir um bom design em vez deprotected
? ObrigadoNão vejo uma razão específica para que isso deva ser desaprovado. Sempre pode haver alternativas para alcançar o mesmo comportamento, e dependerá da arquitetura real se essas alternativas são "melhores" do que um método estático protegido ou não. Mas um exemplo em que um método estático protegido seria razoável, pelo menos, poderia ser o seguinte:
(Editado para dividir em pacotes separados, para facilitar o uso
protected
)Derivado disso:
Outra classe derivada:
O
protected static
modificador certamente pode ser justificado aqui:static
, porque eles não dependem de variáveis de instância. Eles não devem ser usados diretamente como um método polimórfico, mas são métodos de "utilidade" que oferecem implementações padrão que fazem parte de uma computação mais complexa e servem como "blocos de construção" da implementação real.public
, porque são um detalhe de implementação. E eles não podem serprivate
porque devem ser chamados pelas classes que se estendem. Eles também não podem ter visibilidade "padrão", porque não estarão acessíveis para as classes estendidas em outros pacotes.(EDIT: Pode-se supor que o comentário original se refere apenas a campos , e não a métodos - então, no entanto, era muito geral)
fonte
protected final
(já que você não deseja que elas sejam substituídas), nãostatic
. O fato de um método não usar variáveis de instância não significa que deveria serstatic
(embora possa ).final
deixar claro, não apenas deixa claro que o método não deve ser substituído, mas também deixa claro ao leitor que o método não usa variáveis de instância. Tão sucintamente: simplesmente não há razão para não torná-lo estático.protected
, não para mostrar herança, mas para mantê-lo em um único pacote - não exposto. Eu acho que as interfaces selados se tornaria útil dessa maneira quando eles vão em javaprotected
significa "Herdando classes (mesmo em pacotes diferentes)" ...Membros estáticos não são herdados e membros protegidos são visíveis apenas para subclasses (e, claro, a classe que os contém), portanto, a
protected static
tem a mesma visibilidade questatic
, sugerindo um mal-entendido pelo codificador.fonte
protected
não são os mesmos. Se você acabou de dizerstatic
, o campo é visível apenas para subclasses no mesmo pacote.protected static
permite acesso dentro do pacote ou de uma subclasse . Tornar uma variável estática remove as intenções de subclassificação, deixando a única intenção de acessar dentro do pacote.Na verdade, não há nada de fundamentalmente errado
protected static
. Se você realmente deseja uma variável estática ou método visível para o pacote e todas as subclasses da classe declarante, vá em frente e faça issoprotected static
.Algumas pessoas geralmente evitam usar
protected
por várias razões e outras acham questatic
variáveis não finais devem ser evitadas por todos os meios (eu simpatizo pessoalmente com essa última até certo ponto), então acho que a combinaçãoprotected
estatic
deve parecer ruim 2 para aquelas que pertencem a ambos os grupos.fonte
Protected é usado para que possa ser usado em subclasses. Não há lógica na definição de uma estática protegida ao usar no contexto de classes concretas, pois você pode acessar a mesma variável é uma maneira estática. No entanto, o complier emitirá um aviso para acessar a variável estática da superclasse de maneira estática.
fonte
Bem, como a maioria das pessoas respondeu:
protected
significa - ' pacote-privado + visibilidade para subclasses - a propriedade / comportamento é herdado 'static
significa - ' o oposto da instância - é uma propriedade / comportamento de CLASS, ou seja, NÃO É HERDADO 'Portanto, eles são um pouco contraditórios e incompatíveis.
No entanto, recentemente cheguei a um caso de uso em que poderia fazer sentido usar esses dois juntos. Imagine que você deseja criar uma
abstract
classe que é pai de tipos imutáveis e que possui várias propriedades comuns aos subtipos. Para implementar a imutabilidade corretamente e manter a legibilidade, pode-se decidir usar o padrão Builder .E por que
protected static
? Porque eu quero um subtipo não abstrato doAbstactType
qual implemente seu próprio construtor não abstrato e esteja localizado forapackage X
para poder acessar e reutilizar oBaseBuilder
.Claro que podemos tornar
BaseBuilder
público, mas depois chegamos a outras declarações contraditórias:Assim, nos dois casos com
protected static
epublic
construtor de umabstract class
, combinamos declarações contraditórias. É uma questão de preferências pessoais.No entanto, eu ainda prefiro o
public
criador de umabstract class
porque oprotected static
para mim parece mais artificial em um mundo OOD e OOP!fonte
Não há nada errado em ter
protected static
. Uma coisa que muitas pessoas ignoram é que você pode escrever casos de teste para métodos estáticos que não deseja expor em circunstâncias normais. Percebi que isso é particularmente útil para escrever testes para o método estático nas classes de utilidade.fonte