Pertencer à classe, não ao objeto
A maioria dos campos e métodos que você escreveu até agora pertence a objetos: toda vez que você chama new, cada instância ganha sua própria cópia dos campos, e os métodos operam sobre o estado daquele objeto específico. A palavra-chave static inverte isso. Um membro static pertence à própria classe - existe uma única cópia, compartilhada por todas as instâncias, e ela existe independentemente de você criar ou não um objeto.
Essa única distinção explica os campos static, os métodos static, as constantes e até por que main é sempre static.
Um campo static compartilhado
Um campo não estático dá a cada objeto seu próprio espaço. Um campo static dá à classe um espaço que todos compartilham. O exemplo clássico é um contador que registra quantos objetos foram criados:
Repare que você lê o contador como User.count - pelo nome da classe, porque o valor não pertence a nenhum User específico. Cada name, por outro lado, vive dentro do seu próprio objeto. Altere count por qualquer instância e todas as instâncias verão o novo valor, porque existe apenas um.
Métodos static
Um método static também pertence à classe, então você o chama na classe sem um objeto:
Esse é exatamente o padrão por trás da biblioteca padrão: Math.max, Integer.parseInt, Arrays.sort e List.of são todos static - comportamento utilitário que não precisa de um objeto para operar. Recorra a um método static quando o trabalho depende apenas dos seus argumentos, não de nenhum estado específico de um objeto.
A grande pegadinha: static não consegue ver instance
Um método static é executado sem nenhum objeto, então não há this. Isso significa que ele não pode acessar campos de instância nem chamar métodos de instância diretamente - não há um objeto específico de onde lê-los. Esse é o erro mais comum de iniciantes com static:
class Account {
int balance = 100; // campo de instância
static int show() {
return balance; // ERRO DE COMPILAÇÃO: o campo não estático 'balance'
} // não pode ser referenciado a partir de um contexto estático
}
A correção é tornar o método um método de instância (remover static, para que ele tenha um this) ou passar o objeto explicitamente:
O caminho inverso não tem problema: um método de instância pode ler livremente campos static e chamar métodos static, porque os dados compartilhados no nível da classe sempre existem.
Constantes com static final
Combine static com final e você tem uma constante: um único valor compartilhado que nunca pode mudar. Por convenção, são nomeadas em UPPER_SNAKE_CASE:
static final é a forma idiomática de expressar "um valor fixo que pertence ao tipo" - coisas como Integer.MAX_VALUE ou Math.PI na biblioteca padrão. Torná-lo static significa que você não desperdiça uma cópia por objeto; torná-lo final significa que ninguém pode reatribuí-lo.
Blocos inicializadores static
Um campo static simples pode ser inicializado em linha. Quando a configuração precisa de lógica real - montar uma tabela de consulta, ler configurações - use um bloco static. Ele roda uma vez, quando a classe é carregada pela primeira vez, antes de qualquer objeto existir:
O bloco dispara uma única vez, não importa quantas vezes você use a classe, o que o torna o lugar certo para a configuração única que abrange toda a classe.
Quando usar static
Uma regra prática rápida:
- Use um campo static apenas para dados que sejam realmente compartilhados por todas as instâncias - um contador, um cache, uma constante. Se dois objetos pudessem razoavelmente guardar valores diferentes, deveria ser um campo de instância.
- Use um método static quando o resultado depende apenas dos argumentos, não do estado de nenhum objeto (funções utilitárias puras).
- Por padrão, prefira membros de instância. Abusar de
statictransforma silenciosamente seu programa em um amontoado de estado global, difícil de testar e de raciocinar.staticé a exceção, não o ponto de partida.
A seguir: Enums
Uma constante static final serve bem para um único valor fixo, mas quando você tem um conjunto pequeno e fixo de valores relacionados - direções, dias da semana, status de pedidos - o Java tem um tipo feito sob medida que é mais seguro e mais expressivo do que constantes espalhadas. Esse é o enum, e é a próxima página.
Perguntas frequentes
O que significa static em Java?
static significa que um campo ou método pertence à própria classe, não a um objeto individual. Existe exatamente uma cópia de um campo static compartilhada por todas as instâncias, e um método static é chamado na classe (Math.max(...)) sem precisar de um objeto. Membros não estáticos (de instância), por outro lado, ganham uma cópia nova por objeto.
Qual é a diferença entre variáveis static e de instância em Java?
Uma variável de instância tem um valor por objeto - dois objetos podem guardar valores diferentes. Uma variável static tem um único valor compartilhado por todos os objetos da classe, então alterá-la por meio de um objeto (ou pelo nome da classe) fica visível para todos os outros. Use campos de instância para o estado de cada objeto e campos static para dados que sejam realmente globais da classe, como um contador ou uma constante.
Por que o método main é static em Java?
A JVM precisa chamar main antes de qualquer objeto da sua classe existir. Como um método static pertence à classe e não a uma instância, o ambiente de execução pode invocar Main.main(args) diretamente sem construir um Main antes. É por isso que a assinatura é sempre public static void main(String[] args).