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 :)
Pingback: /dev/Kico » Blog Archive » Java 7 vai ter a cara do Groovy?
Pingback: Básico do Groovy para quem for aprender Grails — /dev/Kico
Pingback: Por que Grails é importante para os desenvolvedores Java? — /dev/Kico
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.
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.
Muito interessante q Interpolação de Valores!! o Clousere não entendi o que significa muito bem!
@tgmarinho
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!
Oi Rodrigo, obrigado!
No caso do Groovy, são closures.