O Java está ficando mais charmoso

Click here to read this article in English.

Já tem um bom tempo que eu desisti de acompanhar todas as novidades e tendências no mundo das linguagens de programação. Eu ainda lembro quando comecei a programar, usando Clipper! Para obter novidades, ou você comprava um livro ou uma revista…

Hoje em dia quando visito websites como Reddit ou Digg, sempre me deparo com umas 3 APIs AJAX, todas revolucionárias, alguns artigos dizendo que a linguagem XXX é uma droga porque não tem a feature ABC, enquanto outros arigos dizem que ela é a melhor coisa que já aconteceu para os programadores. Nesse mundo dinâmico de hoje, você tem que filtrar aquelas novidades que você quer “digerir”. Se não o fizer a gente acaba conhecendo muito pouco de muita coisa. 🙂

Então, há algum tempo comecei a ver artigos sobre Closures em Java. Clicava em alguns, dava uma lida por cima, mas nunca me chamou a atenção. Isso foi antes de eu descobrir os Google Tech Talks, e especificamente a série Advanced Topics on Programming Languages. Neste fim de semana passado acabei assistindo uma palestra de 2 horas sobre Java Closures.

O princípio das Closures não é novo. A proposta é usar variáveis com blocos de código (funções). Eu me lembro que no bom e velho Clipper já haviam os code blocks que eram extremamente úteis. Em javascript também é possível utilizar os Function Objects. E por aí vai…

Tento agora explicar de maneira sucinta o que eu entendi das Closures de Java:

Se você já teve que fazer profiling de código, já se deparou com problemas do tipo:

public void metodoProfile1() {
	long t0 = System.currentTimeMillis();
	fazAlgumaCoisa();
	Logger.log(
		"fazAlgumaCoisa(): " + 
		(System.currentTimeMillis() - t0) + 
		" ms."
	);
}

ou em JDBC:

public List getCustomers() {
	List result = new ArrayList();
	Connection conn;
	Statement s;
	ResultSet rs;

	try {
		conn = ConnectionPool.getConnection();
		s = c.createStatement();
		rs = s.executeQuery("SELECT * FROM CUSTOMER");

		while (rs.next()) {
			// ...
		}
	} catch (SQLException e) {
		System.out.println("Error...");
		e.printStackTrace();
	} finally {
		if (conn != null) {
			try {
				conn.close();
			} catch (SQLException e) {
			}
		}
		if (rs != null) {
			try {
				rs.close();
			} catch (SQLException e) {
			}
		}
		if (c != null) {
			try {
				c.close();
			} catch (SQLException e) {
			}
		}
	}
}

Pegue este último exemplo: você tem 37 linhas de código enquanto a lógica está em menos de 10 linhas. Quando um amigo meu diz que java é uma linguagem burocrática, eu tenho que concordar com ele… Imagine tendo que implementar profiling em 50 métodos do seu projeto e fazer classes de acesso à dados da forma do segundo método? Além de um trabalho extremamente braçal e chato, você acaba com replicação de código. Imagine por exemplo que você queira mudar a forma com que você trata exceções para usar uma API nova de logs… São 50 mudanças e por aí vai…

Aí é que a graça das Closures entram! O que você acha se pudesse escrever algo do tipo:

public void metodoProfile1() {
	withMeasure ("metodoProfile1", { =>
		fazAlgumaCoisa();
	});
}

Ou para o caso de JDBC:

public List getCustomers() {
	Connection conn;
	Statement s;
	ResultSet rs;

	with(conn, s, rs, { =>
		conn = ConnectionPool.getConnection();
		s = c.createStatement();
		rs = s.executeQuery("SELECT * FROM CUSTOMER");

		if (rs.next()) {
			// ...
		}
	});
}

Esse bloco de código “{ => … }” é uma nova proposta de sintaxe para o Java que reflete variáveis de função. A sintaxe é simples, alguns exemplos:

{int => int} // protótipo de função que recebe um int e retorna um int

{int, int => int} // protótipo de função que recebe dois int's e retorna um int

{String => int throws NumberFormatException} // recebe uma String e retorna int, 
						// podendo lançar uma NumberFormatException

{ => void } // função sem parâmetros que não retorna nada

{T => U} // função do tipo T que retorna tipo U (generics).

Alguns exemplos de declarações:

{int x => x+1}

{int x, int y => x+y}

{String x => Integer.parseInt(x)}

{=> System.out.println("Hello world");}

{int, int => int} sum = {int x, int y => x+y}; // soma x e y

Toda Closure se transforma “por baixo dos panos” em uma interface que tem um método invoke com a mesma assinatura dos parâmetros da Closure em si. Por exemplo, a variável sum poderia ser executada usando:

(...)
	System.out.println(sum.invoke(5, 2)); // imprime "7"
(...)

… e por aí vai.

O melhor, porém é a sintaxe alternativa, que permite chamadas mais “naturais”. É a chamada “Control Abstract Syntax”, que permite que você escreva o segundo exemplo assim:

public List getCustomers() {
	Connection conn;
	Statement s;
	ResultSet rs;

	with (conn, s, rs) {
		conn = ConnectionPool.getConnection();
		s = c.createStatement();
		rs = s.executeQuery("SELECT * FROM CUSTOMER");

		if (rs.next()) {
			// ...
		}
	}
}

Lindo, não? Pois é… Veja como a parte de “lógica de negócio” agora está bem mais aparente, você não se “destrai” lendo o método… Se você está pensando como fica o método with aqui, dá uma olhada:

public void with(Connection c, Statement s, ResultSet rs, { => void } block) {
	try {
		block.invoke();
	} catch (SQLException e) {
		System.out.println("Error...");
		e.printStackTrace();
	} finally {
		if (rs != null) {
			try {
				rs.close();
			} catch (SQLException e) {
			}
		}
		if (s != null) {
			try {
				s.close();
			} catch (SQLException e) {
			}
		}
		if (c != null) {
			try {
				c.close();
			} catch (SQLException e) {
			}
		}
	}
}

🙂

Este artigo é apenas uma introdução aos Closures em Java. Existem alguns outros apelos para a criação dessa construção. Para maiores informações eu recomendo a apresentação de Neal Gafter, um dos pais da proposta da closures specification. Esse é o link para o vídeo.

Alguns links relacionados:

  • Website de Neal Gafter sobre Closures
  • Neal Gafter blog
  • Peter Ahé’s Weblog (co-autor da especificação)
  • James Gosling, sobre closures
  • Article: Achieving Closures
  • Wikipedia Article sobre Closures
  • Joshua Bloch on Closures, Resource Management, Google tem boas considerações sobre Closures
  • Anúncios

    5 Respostas to “O Java está ficando mais charmoso”

    1. cassiomarques Says:

      Interessante 🙂
      Qualquer coisa que me faça escrever menos código e, consequentemente, torna o pouco que eu escrevo mais manutenível, é muito bem vindo!

    2. Java Closures « Felipe Coury’s Java Corner Says:

      […] Java Closures Click here to read this article in Portuguese. […]

    3. Luis Albinati Says:

      Muito legal Felipe! Não conhecia o tema 🙂
      Ao que parece Gilad Bracha, Neal Gafter, James Gosling e Peter von der Ahé fizeram uma proposta para incluir Closures no Java 7 (Dolphin).

      — Luis

    4. Rubem Azenha Says:

      Excelente explicação felipe 🙂
      Espero que closures entre na Java 7 mesmo!

    5. alex Says:

      interessante artigo levando-se em conta o barulho em torno das linguagens funcionais e o que esperar do java frente a esses desafios

    Deixe um comentário

    Preencha os seus dados abaixo ou clique em um ícone para log in:

    Logotipo do WordPress.com

    Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

    Imagem do Twitter

    Você está comentando utilizando sua conta Twitter. Sair / Alterar )

    Foto do Facebook

    Você está comentando utilizando sua conta Facebook. Sair / Alterar )

    Foto do Google+

    Você está comentando utilizando sua conta Google+. Sair / Alterar )

    Conectando a %s


    %d blogueiros gostam disto: