Archive for março, 2008

Local classes em Java

quarta-feira, março 5th, 2008

Acho que um dos recursos mais desconhecidos da linguagem é a existência das local classes. Local classes são classes definidas dentro de métodos ou blocos em geral, algo como:

public void umMetodo() throws InterruptedException {
    class LocalRunnable implements Runnable {
       private UmBean umBean;

       public void run() {
           umBean = variavelPrivada.fazAlgoLento();
       }

       public UmBean getUmBean() {
          return umBean;
       }
    }

    LocalRunnable lr = new LocalRunnable();
    Thread t = new Thread(lr);
    t.start();

    try {
       t.join();
    } catch (InterruptedException ie) {
       throw ie;
    }

    return lr.getUmBean();
}

No exemplo acima, criamos uma implementação de Runnable que permite obter, após a execução do método run(), o valor computado de uma operação lenta (ok, fora permitir que a thread atual possa ser interrompida enquanto o método executa, não há lá grandes vantagens em criar uma thread para esperar imediatamente pelo seu resultado).

Muitas vezes cria-se uma inner class “nomeada” apenas para ter acesso a alguns métodos adicionais, visto que não é possível chamar normalmente um método de uma anonymous inner class. As local classes resolvem justamente esse problema, como o exemplo acima demonstra.

E você, conhecia esse recurso? Mais informações na JLS.

O infame bug de self-assignment / atribuição a si mesmo

terça-feira, março 4th, 2008

Acabo de ajudar o pessoal do cliente a resolver um erro que é comum em linguagens de programação e que me levou a refletir um pouco.

No caso, havia uma trigger PL/SQL (Oracle 9.x.y.z) em que havia uma variável qualquer, que chamaremos aqui de exemplo. Havia também uma tabela qualquer com uma coluna EXEMPLO – levando em conta que os nomes não são case-sensitive; apenas reflito como estavam sendo usados no código. Era feito um select semelhante a:

SELECT
 INTO 
FROM TABELA T
WHERE T.EXEMPLO = exemplo

E ninguém conseguia entender qual era o bendito erro. Bem, para o Oracle, o where acima é a mesma coisa que:

WHERE T.EXEMPLO = T.exemplo

também conhecido por, hmmm, true. Logo, o where não fazia nem de longe o que o desenvolvedor esperava. Foram perdidas umas 3 horas até que me contaram o problema e eu o detectei imediatamente no código – obviamente, porque também já apanhei disso antes.

A mesma coisa acontece em Java quando uma variável local tem o mesmo nome de uma variável de instância e se esquece de usar o this na atribuição. Qualquer pessoa com um pouco de experiência na linguagem já viu esse erro na vida.

Embora em Java as IDEs detectem esse tipo de erro, eu até hoje não entendo por que essas operações de self-assignment não são reportadas como erro de compilação. Alguém aí tem alguma boa razão para o compilador aceitar isso?

genesis 3.1-RC1

segunda-feira, março 3rd, 2008

No final da semana passada, lançamos o genesis 3.1-RC1. Essa versão possui uma série de correções em relação a 3.0, além de algumas novas funcionalidades.

O genesis é um framework que facilita o desenvolvimento desktop (Swing, SWT e Thinlet) usando um modelo de programação baseado em JavaBeans e anotações que permite ao desenvolvedor focar na lógica de apresentação ao invés de lidar com a API gráfica.

A adoção no Brasil tem sido significativa: o volume de tráfego na lista de usuários em português mostra o aumento da popularidade do framework, e ainda há perguntas postadas em fóruns/comunidades como o SouJava e o GUJ. Esperamos esse ano divulgar mais o projeto e continuar trabalhando para que ele melhore ainda.

Mais informações sobre as novidades podem ser encontradas nas release notes.