Por que ter métodos estáticos privados?

68

Eu só queria esclarecer uma pergunta que tenho. Qual o sentido de ter um método estático privado em oposição a um método normal com visibilidade privada?

Eu teria pensado que uma vantagem de ter um método estático é que ele pode ser chamado sem uma instância de uma classe, mas já que seu particular existe um ponto em que ele é estático?

A única razão pela qual consigo pensar é que ajuda a entender conceitualmente o método no nível da classe, em oposição ao nível do objeto.

Rehan Naqvi
fonte
32
Sim, há uma razão. Seus métodos estáticos públicos / padrão ainda podem chamar suas estáticas privadas. Se métodos estáticos devem ser utilizados e quando é apropriado usar métodos particulares de qualquer tipo, são perguntas separadas, portanto, tenha cuidado para não misturá-los com esta pergunta.
2
Exemplo rápido - método de fábrica usado por uma classe interna que impede a invocação por outras classes (você precisa passar pelo método de fábrica para obter uma instância da classe).
2
@ MattFenwick: você deve postar isso como resposta.
Doc Brown
9
Ao tornar um método estático, você também está dizendo que ele não lê ou grava em variáveis ​​de instância. Um método que não interage com variáveis ​​de instância geralmente é mais fácil de mover e refatorar para outros lugares.
Mark Rogers
11
Não esqueça que, independentemente de um método estático ser privado, interno ou público, ele ainda não é seguro para threads sem um esforço específico de sincronização de código da sua parte.
Craig

Respostas:

70

A característica de ser estático é independente da visibilidade.

Os motivos pelos quais você deseja ter um método estático (algum código que não depende de membros não estáticos) ainda serão úteis. Mas talvez você não queira que mais ninguém use, apenas a sua turma.

Miyamoto Akira
fonte
3
Acho que você está no caminho certo, mas também acho que está perdendo um ponto-chave. A maioria dos métodos estáticos tem zero efeitos colaterais (são efetivamente funções, não métodos) - é por isso que eles são feitos estáticos em primeiro lugar. O argumento contra eles serem privados é "Se eles não têm efeitos colaterais, por que não torná-los públicos para promover a reutilização de código". Esse é o ponto principal: quando o tornamos privado, geralmente é porque queremos que você reutilize toda a classe que usa esse método privado, não apenas esse método.
corsiKa
Devo dizer que nunca fiz isso ou vi esse comportamento. As poucas vezes que o fiz foram para métodos auxiliares para public classes estáticas.
Miyamoto Akira
11
@corsiKa: Efeitos colaterais não são o problema. Tornar um membro estático de uma classe não-privado efetivamente promete que todas as versões futuras de uma classe incluirão o mesmo método com o mesmo nome que faz a mesma coisa. Se as necessidades mudarem, e uma versão futura da classe não precisar de um método que funcione exatamente como o atual, um método privado poderá ser substituído com segurança por um que atenda melhor às novas necessidades da classe. Como um exemplo simples, suponha que uma classe precisa de um método que leva uma string e realiza substituições como <a &lt;, etc. Quando está escrito ...
supercat
11
... as strings pelas quais é passada são conhecidas por não conterem e comercial, e, portanto, não se convertem &em &amp;[se eu estivesse escrevendo o código, eu converteria &em &amp;mesmo que não esperasse que fosse necessário, mas suponha não faz]. É que mais tarde se torna necessário para lidar com ampersands, mas o método é público, alterá-lo para expandir &a &amp;poderia quebrar o código externo que executa sua própria &Para- &amp;substituição. Se o método for privado, no entanto, ele poderá ser corrigido para lidar &sem causar problemas para qualquer código externo.
Supercat
É um problema interessante, para dizer o mínimo, mas não vejo como ser estático o torna mais um problema do que não ser estático, o que é fundamental para esse problema. Se seguirmos sua lógica, tudo em todos os lugares reimplementará tudo porque "omg, e se houver algum bug ou algum requisito mudar algum dia?"
precisa saber é o seguinte
26

Um motivo bastante comum (em Java) seria a inicialização de variáveis ​​de campo imutáveis ​​em um construtor, usando um private staticmétodo simples para reduzir a confusão de construtores.

  • É private: classes externas não devem vê-lo.
  • É static: ele pode executar alguma operação, independente 1 do estado da classe host.

Um exemplo um tanto artificial segue ...

por exemplo:

public class MyClass{
    private final String concatenated;

    public MyClass(String a, String b){
        concatenated = concat(a,b);
    }

    public String getConcatenated(){
       return concatenated;
    }

    /**
    *  Concatenates two Strings as `s1---s2`
    **/
    private static final String concat(String s1, String s2){
        return String.format("%s---%s", s1, s2);
    }
}

1 Supondo que não haja interação com outras staticvariáveis.

Sheldon Warkentin
fonte
15
Isso é ainda mais valioso quando você precisa passar argumentos derivados (calculados) para o construtor de uma superclasse. A super(...)chamada deve ser a primeira linha do construtor da sua classe, portanto você não pode declarar variáveis ​​locais para ajudá-lo a descobrir o que deve ser passado para a super chamada. No entanto, você pode chamar métodos estáticos (privados), que usam quantas linhas são necessárias para calcular o valor a ser transmitido ao super construtor.
Andrzej Doyle
note que há a possibilidade de um bloco inicializador estático
Franz Ebner
13

Um caso de uso comum para um private staticmétodo é um método utilitário que é

  1. usado apenas por essa classe
  2. é independente do estado interno dessa classe
Philipp
fonte
12

Você percebe que possui algumas linhas de código repetidas em muitos dos seus métodos; portanto, decide extraí-las para um único método, pois o código duplicado não é bom.

Você torna o método privado, pois não foi projetado para uso amplo e não deseja que um código não relacionado o chame. (Debata esse ponto nos comentários…)

Como o método não acessa nenhum campo de instância, ele pode tornar-se estático, tornando-o estático para facilitar o entendimento e talvez até um pouco mais rápido.

Então .... (Talvez agora, talvez mais tarde, talvez nunca)

Depois que o método se torna estático, fica claro que ele pode ser movido para fora da classe, digamos, para uma classe unity.

Também é fácil transformá-lo em um método de instância de um de seus parâmetros; geralmente é aqui que o código deve estar.

Ian
fonte
Eu gosto desta resposta, mas você tem alguma referência atualizada para isso? "e talvez até um pouco mais rápido"
Magnilex 23/09/2015
@Magnilex, O ponteiro "this" não é passado para métodos de classe estática; portanto, eles tendem a ser mais rápidos que os métodos de instância estática, a menos que o compilador detecte que "this" não é usado no método de instância (improvável).
Ian Ian
2

Posso pensar em pelo menos duas razões pelas quais você precisaria de um método privado estático em uma classe.

1: Suas instâncias têm motivos para chamar um método estático que você não deseja chamar diretamente, talvez porque compartilhe dados entre todas as instâncias da sua classe.

2: Seus métodos estáticos públicos têm sub-rotinas que você não deseja chamar diretamente. O método ainda é chamado sem uma instância, apenas não diretamente.

Obviamente, "isso ajuda a classe a fazer sentido" é uma boa razão por si só.

DougM
fonte
1

Geralmente, se eu descobrir que estou escrevendo métodos estáticos privados, tomo como uma indicação de que há algo que eu deveria ter modelado separadamente.

Como eles não estão vinculados ao estado de uma instância de objeto específica, uma coleção de métodos estáticos públicos e privados pode formar uma classe totalmente separada com sua própria semântica e métodos não estáticos.

(Outra dica é se eu descobrir que tenho muitos métodos estáticos (públicos e privados) que possuem um parâmetro comum de algum tipo, eles podem ser melhores como membros desse tipo.)

Portanto, para responder sua pergunta, métodos estáticos privados aparecem quando uma classe fornece um grupo de métodos relacionados que são independentes de uma instância dessa classe. (... e, como são independentes, podem ser melhores em sua própria classe.)

Roubar
fonte
-1

Um exemplo muito simples que consigo pensar é: se você deseja processar alguns argumentos de entrada (ou alguma manipulação) que são passados ​​para a função principal. Portanto, neste caso, se o processamento for grande e a mesma funcionalidade não for usada em nenhum outro lugar, fará sentido ter uma função privada, pois não será usada / chamada de nenhum outro lugar + estática, pois main é estática.

techExplorer
fonte