Groovy: detalhes que encantam aqueles que programam em Java

Confesso: estou viciado em Groovy. Desde que aprendi a linguagem a um ano e meio (ou dois?) anos atrás, toda vez que vou programar em Java sinto falta de algum detalhe da sintaxe do Groovy na mesma. Aqui pretendo expor alguns detes pequenos detalhes que, embora não essenciais, são extremamente úteis no dia a dia (e, acredite, você realmente sentiria falta dos mesmos ao trabalhar com Java). Estes detalhes tornariam Groovy um Java++?

Strings

Interpolação de valores:

Java

int valorInteiro = 3;
// No java pré 5 
String valor = "O valor inteiro vale" + Integer.toString(valorInteiro);
// No java 5 e posterior (bem melhor!)
String valor5 = "O valor inteiro vale " + valorInteiro

Groovy

int valorInteiro = 3
// Repare: sem concatenação de Strings!
String valor = "O valor inteiro vale ${valorInteiro}"

Strings com mais de uma linha

Java

String multiLinha = "Esta é a minha string \n" +
                         "com mais de uma \n" +
                         "linha!"

Groovy

String multiLinha = """Uma string com áspas triplas
                             me permite escrever strings
                             com quantas linhas eu
                             quiser"""

Evitando NullPointerException

Java

 Object valor = construaObjeto();
 if (valor != null) { // bla bla bla }

Groovy

 def valor = construaObjeto()
 if (valor) {//bla bla bla}

Em Groovy, a verdade nem sempre é um booleano. Um valor nulo equivale a um false tradicional.

Verificando valores nulos na concatenação de uma string
Java

 Object obj = criarObjeto();
 String str = "O valor do objeto será igual a " + obj == null ? "nulo" : obj.toString();

Groovy

 Object obj = criarObjeto()
 String str = "O valor do objeto será igual a ${?obj.toString()}"

Criando getters e setters

Convenhamos: um dos recursos mais utilizados em nossas IDE´s consiste na opção de refatoração que encapsula atributos gerando getters e setters. Em Java, quando precisamos criar getters e setters, precisamos digitá-los explicitamente em nosso código, tal como no exemplo abaixo:
Java

class ClasseQuente {
   private int valor;
   public int getValor() {return this.valor;}
   public void setValor(int v) {this.valor = v;}

  private String texto;
  public String getTexto() {return this.texto;}
  public void setTexto(String v) {this.texto = v;}
}

Em groovy…
Groovy

class ClasseQuentissima {
     int valor
     String texto
}

Se coloco o acesso padrão, não preciso criar gets e sets explícitamente! Groovy os cria para nós em tempo de execução. Simples não?

return opcional

Em Java, sempre que quero retornar um valor, preciso de usar a palavra-chave return. Em Groovy, o último comando de um bloco de código corresponde ao valor retornado. Exemplo:

  int soma(int a, int b) {
      a + b
  }

Closures

Closures encontram-se previstas para serem incluídas no Java 7, mas antes de expô-las, convém perguntar: que bicho é este?

Basicamente, closures são um tipo de dados que, na realidade, consiste em um bloco de código executável. Você pode então ter variáveis em seu código que, na realidade, são código executável, tal como no exemplo abaixo:

  def closureQuente = {
        print "\nSou uma closure. Ao ser chamada, imprimo isto!"
  }

Uma closure também pode ter parâmetros, tal como em

   def closureQuenteComParametros = {a, b ->
         a + b}

E como eu poderia usar tais valores em Java? Em qualquer situação na qual determinado método de uma classe tenha de ser definido dinamicamente. Imagine, por exemplo, a utilização de closures em um enum. Abaixo exponho como imagino que as closures poderiam ser definidas em Java neste caso:

enum OperacoesMatematicas {

   Soma({a, b -> return a+b;}),
   Subtracao({a,b -> return a-b;});

   Closure operacao;
   getOperacao() {return this.operacao;}

   
   OperacoesMatematicas(Closure o) {this.operacao = o;}
}

Estes são apenas alguns dos detalhes que me encantaram em Groovy quando comecei a aprender a lingaugem. São suficientes para que eu troque de linguagem definitivamente? Claro que não! Java ainda apresenta uma performance muito superior e, querendo ou não, na JVM, é a lingaugem padrão. Isto sem mencionar que não existe um Groovy Community Process, tal como ocorre no caso do Java.

E aqui fico ansioso para, no futuro, escrever algo neste blog como Linguagem X (pode até ser Java): detalhes que encantam aqueles que programam em Groovy :)

8 Comments

Add Yours →

[…] Antes de começarmos a trabalhar diretamente com Grails, convém conhecer o básico do Groovy. Afinal de contas, é a linguagem por trás da ferramenta e, mais do que isto, trata-se também de uma linguagem muito interessante para se trabalhar (programadores Java podem ver varios detalhes da linguagem que realmente surpreendem). […]

Eu tenho uma classe Usuario em groovy e Usuario tem nome e sobrenome.

A partir de uma lista de Usuarios como eu crio uma lista pegando apenas os sobrenomes da minha lista de Usuario?

Abs.

Responda

admin Reply:

Oi Gus, sugiro que você poste esta sua dúvida no Grails Brasil (http://www.grailsbrasil.com). Lá poderei te dar todo o suporte necess[ario – além de, é claro, toda a comunidade que trabalha com a ferramenta.

Responda

Olá,

Estou acompanhando os artigos do /dev/kiko para começar a aprender Groovy e Grails. O material está ótimo até agora, muito obrigado :-)

Queria fazer uma sugestão sobre este tópico específico: Não está claro no texto se o que o Grails suporta são de fato closures ou apenas funções lambda. Os exemplos mostram apenas o uso de expressões lambda, pois não vemos um exemplo em que o contexto externo fica armazenado. Acho que na época em que o artigo foi escrito (2008) tudo era muito novidade, nem se fazia muita distinção entre esses conceitos, mas agora seria legal dar uma incrementada.

E mais uma vez, obrigado por oferecer este material!

Responda

Kico (Henrique Lobo Weissmann) Reply:

Oi Rodrigo, obrigado!
No caso do Groovy, são closures.

Responda

Deixe um comentário

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.