HOWTO · Java

Classe estática em Java

Este artigo apresenta as classes estáticas Java.

Nesta página

Java não permite declarar uma classe de nível superior como static. Uma classe declarada dentro de outra pode usar static; ela é uma classe aninhada estática. É possível instanciá-la sem criar uma instância da classe envolvente, e ela pode usar os membros estáticos dessa classe. Se você quer uma classe utilitária que os chamadores não possam instanciar pela API pública, use um construtor privado; esse é um padrão de projeto distinto.

O que é uma classe aninhada estática em Java?

Uma classe aninhada estática é um tipo membro declarado com a palavra-chave static dentro de outra classe. O modificador static significa que uma instância da classe aninhada não tem uma referência implícita a um objeto da classe envolvente. Isso não significa que a própria classe aninhada não possa ser instanciada. Seu tipo é acessado por meio do tipo envolvente, como Container.Entry, e um método de instância é chamado em uma instância desse tipo aninhado.

Uma classe aninhada estática pode acessar os membros estáticos da classe envolvente, inclusive os privados. Ela não pode se referir aos campos ou métodos de uma instância envolvente como se tivesse um objeto envolvente. Isso é possível quando um objeto da classe envolvente é fornecido explicitamente.

Como declarar e usar uma classe aninhada estática

Declare a classe membro com static e use o nome do tipo envolvente para instanciá-la. Este exemplo completo também mostra o acesso a um campo estático da classe envolvente:

Execute este exemplo:

O código e os rótulos ou saídas exibidos nesta seção permanecem em inglês.

public class Container {
    private static int count = 3;

    public static class Entry {
        public int value() {
            return count;
        }
    }

    public static void main(String[] args) {
        Container.Entry entry = new Container.Entry();
        System.out.println(entry.value());
    }
}
3

A execução do exemplo imprime 3. Ao adaptá-lo, mantenha a classe aninhada dentro da classe envolvente e qualifique seu tipo como Container.Entry fora de Container. O objeto Entry é uma instância comum, enquanto count pertence à própria classe envolvente.

Classe aninhada estática versus classe interna

Uma classe membro não estática é comumente chamada de classe interna. Para instanciá-la, é preciso ter uma instância envolvente: crie um objeto Container e, em seguida, use container.new Inner(). Uma instância de classe interna pode usar diretamente os membros de instância do objeto envolvente, pois mantém essa associação.

Uma classe aninhada estática não tem essa associação implícita. Para ler um campo de instância da classe envolvente, passe ou obtenha de outra forma um objeto Container e acesse o campo por meio dessa referência. Os dois tipos de classes aninhadas podem acessar os membros permitidos pelas regras de acesso de tipos aninhados do Java; a diferença principal é se uma instância envolvente fica disponível automaticamente.

Como criar uma classe utilitária que não pode ser instanciada

Uma classe utilitária reúne operações ou constantes que não precisam de estado por objeto. Coloque esses membros em uma classe comum de nível superior, marque como static os membros apropriados e adicione um construtor private para que chamadores comuns não possam usar new fora da classe. Por exemplo, o padrão é public final class TextTools { private TextTools() {} public static String join(String first, String second) { return first + second; } }; chame-o como TextTools.join("static ", "utility").

O construtor privado impede a instanciação externa comum, mas não transforma TextTools em uma classe estática; Java não tem classes estáticas de nível superior. Declarar a classe como final é opcional e apenas impede a criação de subclasses. Use essa restrição quando ela fizer parte do projeto, não como requisito para métodos utilitários.

Equívocos comuns sobre classes estáticas

Uma classe aninhada estática pode ser instanciada; static elimina a necessidade de uma instância envolvente implícita. Seus métodos de instância podem usar os próprios campos de instância. O nome da classe envolvente qualifica o tipo aninhado, mas ainda é necessário um objeto do tipo aninhado para chamar seus métodos de instância.

Um contexto estático não pode acessar um membro de instância da classe envolvente pelo nome sem qualificação, pois nenhum objeto envolvente fica disponível automaticamente. Ele pode acessar esse membro por meio de uma referência explícita a um objeto. Da mesma forma, um construtor utilitário privado impede chamadas comuns feitas de fora da classe, mas não torna a instanciação impossível em todas as circunstâncias. Essas distinções separam a sintaxe de classes aninhadas do Java do padrão de classe utilitária.