CodeGym /Cursos /JAVA 25 SELF /Métodos static em interfaces

Métodos static em interfaces

JAVA 25 SELF
Nível 21 , Lição 3
Disponível

1. Introdução

Até o Java 8, uma interface era exclusivamente “contrato”: apenas métodos abstratos, nenhuma implementação, nenhuma lógica — só promessas. Mas, a partir do Java 8, as interfaces ficaram um pouco mais “autônomas”: agora elas podem conter não apenas métodos default, mas também static-métodos.

Métodos static em interfaces — são métodos que pertencem à própria interface, e não às suas implementações (classes). Eles não exigem a criação de um objeto e são chamados diretamente pelo nome da interface.

Analogia:
Métodos static em interfaces são como um guia ou lembrete colado na parede do escritório: cada funcionário (classe) pode usá-lo, mas o lembrete não pertence a nenhum funcionário em particular.

Métodos static em interfaces permitem agrupar funções utilitárias relacionadas a essa interface sem poluir o espaço de nomes das classes que a implementam.

Sintaxe de métodos static em interfaces

Métodos static são declarados dentro da interface com a palavra-chave static. Eles podem conter implementação (código dentro de chaves) e só podem ser chamados pelo nome da interface.

Exemplo:

public interface MathUtils {
    static int sum(int a, int b) {
        return a + b;
    }

    static double average(int a, int b) {
        return (a + b) / 2.0;
    }
}

Chamada de um método static da interface:

int result = MathUtils.sum(5, 7);        // 12
double avg = MathUtils.average(10, 20);  // 15.0

Atenção:
Não é possível chamar um método static de interface por meio de uma classe que a implementa ou de um objeto! Somente pelo nome da interface.

2. Em que os métodos static de interface diferem dos métodos default?

Métodos static:

  • Pertencem à própria interface.
  • Não são herdados pelas classes que a implementam.
  • Não podem ser chamados por meio de um objeto da classe.
  • Não podem ser sobrescritos na classe que implementa.
  • Podem ser chamados apenas pelo nome da interface.

Métodos default:

  • Pertencem ao objeto (instância) da classe que implementa a interface.
  • Podem ser sobrescritos na classe que implementa.
  • Podem ser chamados por meio do objeto da classe que implementa.
  • São herdados pelas classes que implementam.

Resumo: os default-métodos ampliam as capacidades do objeto, enquanto os static-métodos ampliam as da própria interface.

Exemplo de comparação:

interface Printer {
    default void print(String text) {
        System.out.println("Default: " + text);
    }

    static void info() {
        System.out.println("Printer interface v1.0");
    }
}

class ConsolePrinter implements Printer {}

public class Main {
    public static void main(String[] args) {
        Printer.info(); // Chamada de método static via interface

        ConsolePrinter cp = new ConsolePrinter();
        cp.print("Hello!"); // Chamada de método default via objeto
        // cp.info(); // Erro! Um método static não pode ser chamado por um objeto
    }
}

3. Por que precisamos de métodos static em interfaces?

Antes dos métodos static em interfaces, se você precisasse adicionar uma função utilitária relacionada à interface, era preciso criar classes separadas com sufixo Utils ou Helper:

public interface Movable {
    void move(int x, int y);
}

public class MovableUtils {
    public static void resetPosition(Movable m) {
        m.move(0, 0);
    }
}

Agora é possível fazer isso diretamente na interface:

public interface Movable {
    void move(int x, int y);

    static void resetPosition(Movable m) {
        m.move(0, 0);
    }
}

Isso torna o código mais lógico e coeso: métodos relacionados à interface agora vivem nela própria.

Vantagens:

  • Agrupamento de funções utilitárias junto ao contrato da interface.
  • Não “poluem” o espaço de nomes das classes que a implementam.
  • Melhoram a legibilidade e a manutenção do código.

4. Restrições e particularidades dos métodos static de interface

Métodos static de interface não são herdados pelas classes que a implementam.

Eles não podem ser chamados por meio de um objeto da classe que implementa nem pelo nome da classe. Apenas pelo nome da interface!

Métodos static em uma interface sempre contêm implementação: eles não podem ser abstract ou default.

Eles sempre contêm implementação.

Métodos static não podem acessar métodos ou variáveis não estáticos da interface.

Eles só podem acessar outros membros static da interface (por exemplo, static final constantes).

Métodos static de interface podem ser privados (Java 9+).

É possível criar métodos private static auxiliares para uso dentro da interface.

5. Exemplo: métodos static para a interface Movable

Vamos ver como adicionar métodos static à interface Movable. Suponha que temos a interface Movable, que é implementada por diferentes classes (por exemplo, robôs, animais, veículos).

Passo 1. Declarar a interface com um método static:

public interface Movable {
    void move(int x, int y);

    static void resetPosition(Movable obj) {
        obj.move(0, 0);
    }

    static double distance(int x1, int y1, int x2, int y2) {
        int dx = x2 - x1;
        int dy = y2 - y1;
        return Math.sqrt(dx * dx + dy * dy);
    }
}

Passo 2. Implementar a interface em uma classe:

public class Robot implements Movable {
    private int x, y;

    public Robot(int x, int y) {
        this.x = x;
        this.y = y;
    }

    @Override
    public void move(int x, int y) {
        System.out.println("O robô se move para o ponto (" + x + "," + y + ")");
        this.x = x;
        this.y = y;
    }

    public void printPosition() {
        System.out.println("Posição atual: (" + x + "," + y + ")");
    }
}

Passo 3. Usar os métodos static da interface:

public class Main {
    public static void main(String[] args) {
        Robot robby = new Robot(10, 15);
        robby.printPosition();

        // Reset de posição via método static da interface
        Movable.resetPosition(robby);
        robby.printPosition();

        // Cálculo da distância entre pontos via método static da interface
        double dist = Movable.distance(0, 0, 10, 15);
        System.out.println("Distância: " + dist);
    }
}

Resultado:

Posição atual: (10,15)
O robô se move para o ponto (0,0)
Posição atual: (0,0)
Distância: 18.027756377319946

Observe:
Chamamos Movable.resetPosition(robby), e não robby.resetPosition(). Métodos static são convenientes para operações que pertencem logicamente à interface, e não a um objeto específico.

6. Métodos private static em interfaces

Às vezes, é necessário usar na interface métodos auxiliares apenas para necessidades internas (por exemplo, para não duplicar código em vários métodos static ou default). A partir do Java 9, as interfaces suportam private static-métodos.

Exemplo:

public interface Logger {
    static void logInfo(String message) {
        log("INFO", message);
    }
    static void logError(String message) {
        log("ERROR", message);
    }
    private static void log(String level, String message) {
        System.out.println("[" + level + "] " + message);
    }
}

Agora log() não está acessível fora da interface, mas é usado dentro de outros métodos static.

7. Onde há métodos static na biblioteca padrão do Java?

Métodos static em interfaces são amplamente usados na biblioteca padrão do Java, especialmente em coleções e interfaces funcionais.

Exemplos:

  • Comparator.comparing(), Comparator.reverseOrder() — métodos static da interface Comparator.
  • Predicate.isEqual() — método static da interface Predicate.
  • List.of(), Set.of(), Map.of() (Java 9+) — métodos static para criar coleções imutáveis.

Exemplo com Comparator:

import java.util.Comparator;

public class Main {
    public static void main(String[] args) {
        Comparator<String> cmp = Comparator.reverseOrder();
        int res = cmp.compare("a", "b"); // número positivo, porque "a" > "b" na ordem reversa
        System.out.println(res);
    }
}

8. Erros típicos ao trabalhar com métodos static de interface

Erro nº 1: tentar chamar um método static por meio de um objeto da classe que implementa.
Isso não vai funcionar! Um método static de interface é chamado apenas pelo nome da interface, por exemplo, Movable.resetPosition(obj), e não obj.resetPosition().

Erro nº 2: tentar sobrescrever um método static da interface na classe que implementa.
Métodos static não são herdados e não são sobrescritos! Se você declarar na classe um método static com o mesmo nome, será um método totalmente diferente, sem relação com a interface.

Erro nº 3: esquecer que métodos static não podem acessar membros não estáticos.
Métodos static de interface podem usar apenas membros static (por exemplo, constantes static final), e não podem acessar métodos ou variáveis não estáticos.

Erro nº 4: confusão com métodos default.
default-métodos são chamados pelo objeto; static, apenas pelo nome da interface. Não confunda!

Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION