Métodos static em Interfaces do Java 8 simplificam e reduzem seu código, além de poderem aumentar sua produtividade. Aprenda agora e aumente a qualidade do seu código!
Métodos static
em classes utilitárias
É comum a necessidade de criar métodos static
para que possam ser chamados sem a necessidade de criar um novo objeto. A própria JDK possui várias classes que contém somente métodos static
, por exemplo: java.lang.Math
, java.util.Collections
, java.util.Arrays
, java.util.stream.Streams
.
E a JDK deixa claro que não quer que você crie instâncias dessas classes. Veja os construtores retirados diretamente do código fonte da JDK:
// Suppresses default constructor, ensuring non-instantiability. private Collections() { }
// Suppresses default constructor, ensuring non-instantiability. private Arrays() {}
/** * Don't let anyone instantiate this class. */ private Math() {}
private Streams() { throw new Error("no instances"); }
Além disso, inúmeras bibliotecas disponibilizam classes utilitárias que também contém apenas métodos static
, como aquelas dos projetos Apache Commons.
O problema com classes utilitárias
Esse tipo de classe normalmente é chamada de utilitária, por isso a terminação *Util
em muitas delas, principalmente nas da Apache. Essas classes basicamente não seguem o padrão de Orientação à Objetos (OO), pois contém apenas código estruturado.
Aliás, se fosse possível no Java, esses métodos nem estariam dentro de uma classe.
Quando utilizar classes utilitárias?
O fato de não seguir os conceitos da OO não é necessariamente algo ruim. Porém, imagine a seguinte situação: você possui uma classe Pessoa
e quer fazer um método utilitário static
. O que você acha que faz mais sentido: criar uma classe PessoaUtil
com esse método, ou criá-lo na própria classe Pessoa
? Eu advogo pela segunda opção. Ou seja, só vejo sentido em criar uma classe utilitária quando:
- Você não é o dono da classe original, ou não consegue modificá-la; ou
- Você possui uma estrutura de interfaces e esse método utilitário serve para todas elas. Este é o caso da classe
java.util.Collections
.
Quer dizer, eu defendia isso até o Java 8. Agora, no segundo caso, a própria interface pode ter métodos static
.
Métodos static
em Interfaces do Java 8
A partir do Java 8, é possível criar métodos static
na própria interface:
interface Corredor { static double calculeVelocidade(double tempo, double distancia) { return distancia/tempo; } }
Ou seja, nesse caso, é possível chamar o método da Interface sem instanciar um novo objeto:
double velocidade = Corredor.calculeVelocidade(5.0, 10.0); System.out.println(velocidade);
Sendo assim, mesmo que você tenha uma estrutura de interfaces, você poderia criar seus métodos static
dentro da interface apropriada.
Claro, existem exceções à regra, e talvez ainda há casos parecidos em que faça sentido criar uma classe utilitária. A questão é que agora você tem uma nova opção a considerar.
Métodos static
em Interfaces NÃO fazem parte da API
É muito importante lembrar que os métodos criados como static
não fazem parte da API da Interface. Ou seja, eles realmente são elementos da Interface. Assim como métodos static
de uma classe são elementos da classe.
Por isso, o código abaixo não compila, por conta das linhas 3 e 7.
public static void main(String[] args) { // NÃO COMPILA - a classe Pessoa não possui o método calculeVelocidade double velocidade = Pessoa.calculeVelocidade(5.0, 10.0); System.out.println(velocidade); // NÃO COMPILA - o objeto instância de Pessoa não possui o método calculeVelocidade double velocidade2 = new Pessoa().calculeVelocidade(5.0, 10.0); System.out.println(velocidade2); } interface Corredor { static double calculeVelocidade(double tempo, double distancia) { return distancia/tempo; } } class Pessoa implements Corredor {}
Ou seja, não é possível chamar o método static
da interface diretamente em classes que implementam aquela interface.
Métodos static
em Interfaces são public
e NÃO são abstract
Por definição, até o Java 8, todos os métodos de uma interface eram public
e abstract
, mesmo que você não declarasse-os assim. Veja no exemplo abaixo:
interface Corredor { public abstract void correr(); void correrRapido(); // também é public e abstract }
Os métodos static
continuam sendo obrigatoriamente public
, porém não são abstract
. E faz todo sentido, afinal eles contém uma implementação.
Parabéns! Agora você conhece melhor as interfaces do Java 8! Você pode utilizar esse conhecimento para entregar no prazo soluções de alta qualidade.
E você? Já utiliza métodos static em Interfaces? Já teve que dar manutenção em algum código assim? Lembra de situações em que você poderia ter se beneficiado dessa nova opção? Deixe um comentário!