Recentemente, estive olhando meus avisos no Eclipse e encontrei este:
Ele dará um aviso do compilador se o método puder ser declarado como estático.
[editar] Citação exata dentro da ajuda do Eclipse, com ênfase em privado e final:
Quando ativado, o compilador emitirá um erro ou um aviso para métodos que são privados ou finais e que se referem apenas a membros estáticos.
Sim, eu sei que posso desligá-lo, mas quero saber o motivo de ligá-lo.
Por que seria uma boa coisa declarar todos os métodos possíveis como estáticos?
Isso trará algum benefício de desempenho? (em um domínio móvel)
Apontar um método como estático, suponho que esteja mostrando que você não usa nenhuma variável de instância, portanto, poderia ser movido para uma classe de estilo utils?
No final do dia, devo apenas desligar "ignorar" ou devo corrigir os mais de 100 avisos que ele me deu?
Você acha que são apenas palavras-chave extras que sujam o código, já que o compilador apenas embutirá esses métodos de qualquer maneira? (como se você não declarasse todas as variáveis que pode finalizar, mas poderia ).
fonte
Respostas:
Sempre que você escreve um método, você cumpre um contrato em um determinado escopo. Quanto mais estreito for o escopo, menor será a chance de você escrever um bug.
Quando um método é estático, você não pode acessar membros não estáticos; portanto, seu escopo é mais estreito. Portanto, se você não precisa e nunca precisará (mesmo em subclasses) de membros não estáticos para cumprir seu contrato, por que conceder acesso a esses campos ao seu método? Declarar o método
static
neste caso permitirá que o compilador verifique se você não usa membros que não pretende usar.E, além disso, ajudará as pessoas que estão lendo seu código a entender a natureza do contrato.
É por isso que é considerado bom declarar um método
static
quando ele está realmente implementando um contrato estático.Em alguns casos, seu método significa apenas algo relativo a uma instância de sua classe, e acontece que sua implementação não usa nenhum campo ou instância não estático. Nesses casos, você não marcaria o método
static
.Exemplos de onde você não usaria a
static
palavra-chave:fonte
private
método pudesse ser declarado estático, quase invariavelmente deveria ser. Para qualquer outro nível de acesso, há outros fatores a serem considerados, como despacho dinâmico.object.method()
selecionar o método a ser chamado.Não há conceito de otimização aqui.
Um
static
método ocorrestatic
porque você declara explicitamente que o método não depende de nenhuma instância da classe envolvente apenas porque não precisa. Portanto, esse aviso do Eclipse, conforme declarado na documentação:Se você não precisa de nenhuma variável de instância e seu método é privado (não pode ser chamado de fora) ou final (não pode ser substituído), então não há razão para permitir que seja um método normal ao invés de um estático. Um método estático é inerentemente mais seguro, mesmo porque você tem permissão para fazer menos coisas com ele (não precisa de nenhuma instância, você não tem nenhum
this
objeto implícito ).fonte
Não tenho informações sobre o desempenho, suponho que seja um pouco melhor, no máximo, já que o código não precisa fazer despacho dinâmico com base no tipo.
No entanto, um argumento muito mais forte contra a refatoração em métodos estáticos é que atualmente o uso de estático é considerado uma prática ruim. Variáveis / métodos estáticos não se integram bem em uma linguagem orientada a objetos e também são difíceis de testar adequadamente. Esta é a razão pela qual algumas linguagens mais recentes abandonam o conceito de métodos / variáveis estáticos completamente, ou tentam internalizá-lo na linguagem de uma forma que funcione melhor com OO (por exemplo, Objetos em Scala).
Na maioria das vezes, você precisa de métodos estáticos para implementar funções que estão usando apenas parâmetros como uma entrada e produzindo uma saída usando isso (por exemplo, funções de utilitário / auxiliar). Em linguagens modernas, há um conceito de função de primeira classe que permite isso, então estático Não é necessário. Java 8 terá expressões lambda integradas, portanto, já estamos avançando nessa direção.
fonte
private static
métodos para que você não precise zombar deles1. Método de declaração
static
oferece um pequeno benefício de desempenho, mas o que é mais útil, permite usá-lo sem ter uma instância de objeto em mãos (pense, por exemplo, no método de fábrica ou na obtenção de um singleton). Também serve ao propósito documental de contar a natureza do método. Este propósito documental não deve ser ignorado, pois dá dicas imediatas sobre a natureza do método para os leitores do código e usuários da API e também serve como uma ferramenta de pensamento para o programador original - ser explícito sobre o significado pretendido ajuda você também pensa com clareza e produz código de melhor qualidade (acho que com base na minha experiência pessoal, mas as pessoas são diferentes). Por exemplo, é lógico e, portanto, desejável distinguir entre métodos que operam em um tipo e métodos que agem em uma instância do tipo (como apontado porJon Skeet em seu comentário a uma questão C # ).Ainda outro caso de uso para
static
métodos é imitar a interface de programação procedural. Pense najava.lang.System.println()
classe e nos métodos e atributos nela contidos. A classejava.lang.System
é usada como um espaço de nomes de agrupamento, em vez de um objeto instanciável.2. Como pode o Eclipse (ou qualquer outro tipo de entidade programada ou outro tipo de - biocomponível ou não biocomponível -) saber com certeza qual método pode ser declarado como estático? Mesmo se uma classe base não estiver acessando variáveis de instância ou chamando métodos não estáticos, pelo mecanismo de herança as coisas podem mudar. Somente se o método não pode ser substituído pela subclasse herdada, podemos afirmar com 100% de certeza que o método realmente pode ser declarado
static
. Substituir um método é impossível exatamente nos dois casos de serprivate
(nenhuma subclasse pode usá-lo diretamente e nem mesmo em princípio sabe sobre ele), oufinal
(mesmo se acessível pela subclasse, não há como alterar o método para se referir a dados de instância ou funções).Daí a lógica da opção Eclipse.
3. O autor da postagem original também pergunta: “ Apontar um método como estático, suponho que esteja mostrando que você não usa nenhuma variável de instância, portanto, poderia ser movido para uma classe de estilo utils? ” Este é um ponto muito bom. Às vezes, esse tipo de alteração de design é indicado pelo aviso.
É uma opção muito útil, que eu pessoalmente me certificaria de habilitar, se eu usasse o Eclipse e fosse programar em Java.
fonte
Veja a resposta de Samuel sobre como o escopo do método muda. Acho que esse é o aspecto principal de tornar um método estático.
Você também perguntou sobre o desempenho:
Pode haver um pequeno ganho de desempenho, porque uma chamada para um método estático não precisa da referência implícita "this" como parâmetro.
No entanto, esse impacto no desempenho é muito pequeno. Portanto, é tudo sobre o escopo.
fonte
Das diretrizes de desempenho do Android:
http://developer.android.com/training/articles/perf-tips.html#PreferStatic
fonte
Bem, a documentação do Eclipse diz sobre o aviso em questão:
Acho que diz tudo. Se o método for privado e final e se referir apenas a membros estáticos, o método em questão pode muito bem ser declarado estático e, por isso, tornar evidente que pretendemos apenas acessar conteúdo estático a partir dele.
Sinceramente, não acho que haja qualquer outra razão misteriosa por trás disso.
fonte
Faltavam alguns números para as diferenças de velocidade. Então tentei fazer um benchmark, o que acabou não sendo tão fácil: o Java loop fica mais lento após algumas execuções / falha do JIT?
Finalmente usei o Caliper e os resultados são os mesmos de fazer meus testes manualmente:
Não há diferença mensurável para chamadas estáticas / dinâmicas. Pelo menos não para Linux / AMD64 / Java7.
Os resultados do Caliper estão aqui: https://microbenchmarks.appspot.com/runs/1426eac9-36ca-48f0-980f-0106af064e8f#r:scenario.benchmarkSpec.methodName,scenario.vmSpec.options.CMSLargeCoalSurplusPercent,Scenario.vm CMSLargeSplitSurplusPercent, scenery.vmSpec.options.CMSSmallCoalSurplusPercent, scenery.vmSpec.options.CMSSmallSplitSurplusPercent, scenery.vmSpec.options.FLSLargestBlockCoalesceProximity. scenery.varktionsSpecuration
e meus próprios resultados são:
A classe de teste Caliper foi:
E minha própria classe de teste foi:
fonte
Os métodos que você pode declarar como estáticos são aqueles que não requerem instanciação, como
Que você pode então chamar de volta em qualquer outra classe sem instanciar aquela classe.
... Mas isso é algo que você provavelmente já sabe. Ele não oferece nenhum benefício real per se, a não ser deixar mais claro que o método não usa nenhuma variável de instância.
Em outras palavras, você pode simplesmente desligá-lo completamente com segurança. Se você sabe que nunca usará um método em outras classes (nesse caso, ele deve ser apenas privado), você não precisa que ele seja estático.
fonte